/**
 *
 * @author 4refr0nt
 * @cn Minuy 20200627
 */
package ESPlorer;

import java.awt.Color;
import java.awt.Toolkit;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.logging.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.prefs.*;

import java.net.*;
import java.util.HashMap;

import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.Timer;
import javax.swing.UIManager.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

import org.fife.ui.rsyntaxtextarea.*;
import org.fife.ui.autocomplete.*;

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import jssc.SerialPortList;

public class ESPlorer extends javax.swing.JFrame {

    public static SerialPort serialPort;
    public static ArrayList<String> sendBuf;
    public static boolean pasteMode = true; // for MicroPython only

    public static boolean pOpen = false;
    public static boolean sOpen = false;
    public static boolean portJustOpen = false;
    public static final String VERSION = "v0.2.0-cn1";
    private static String laf;
    private static String systemLaf;
    public static Preferences prefs;
    private static int FirmwareType;

    private static final pyFiler PYFILER = new pyFiler();

    /**
     * Creates new form MainWindows
     */
    public ESPlorer() {
        try {
            FileHandler fh = new FileHandler("ESPlorer.Log");
            LOGGER.addHandler(fh);
        } catch (SecurityException e) {
            LOGGER.log(Level.SEVERE, "内部错误105:不能创建日志文件。没有权限。", e);
//            LOGGER.log(Level.SEVERE,e.getStackTrace().toString(), e);
//            e.printStackTrace();
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "内部错误106:不能创建日志文件。I / O错误。", e);
//            LOGGER.log(Level.SEVERE,e.getStackTrace().toString(), e);
//            e.printStackTrace();
        }
        initComponents();
        finalInit();

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        ContextMenuTerminal = new javax.swing.JPopupMenu();
        MenuItemTerminalClear = new javax.swing.JMenuItem();
        MenuItemTerminalCopy = new javax.swing.JMenuItem();
        TerminalSeparator1 = new javax.swing.JPopupMenu.Separator();
        MenuItemTerminalFontInc = new javax.swing.JMenuItem();
        MenuItemTerminalFontDec = new javax.swing.JMenuItem();
        TerminalSeparator2 = new javax.swing.JPopupMenu.Separator();
        MenuItemTerminalReset = new javax.swing.JMenuItem();
        MenuItemTerminalFormat = new javax.swing.JMenuItem();
        ContextMenuEditor = new javax.swing.JPopupMenu();
        MenuItemEditorUndo = new javax.swing.JMenuItem();
        MenuItemEditorRedo = new javax.swing.JMenuItem();
        EditorSeparator1 = new javax.swing.JPopupMenu.Separator();
        MenuItemEditorSendSelected = new javax.swing.JMenuItem();
        MenuItemEditorSendLine = new javax.swing.JMenuItem();
        EditorSeparator = new javax.swing.JPopupMenu.Separator();
        MenuItemEditorCut = new javax.swing.JMenuItem();
        MenuItemEditorCopy = new javax.swing.JMenuItem();
        MenuItemEditorPaste = new javax.swing.JMenuItem();
        EditorSeparator2 = new javax.swing.JPopupMenu.Separator();
        MenuItemEditorFontInc = new javax.swing.JMenuItem();
        MenuItemEditorFontDec = new javax.swing.JMenuItem();
        ContextMenuLog = new javax.swing.JPopupMenu();
        MenuItemLogClear = new javax.swing.JMenuItem();
        MenuItemLogClose = new javax.swing.JMenuItem();
        LogSeparator = new javax.swing.JPopupMenu.Separator();
        MenuItemLogFontInc = new javax.swing.JMenuItem();
        MenuItemLogFontDec = new javax.swing.JMenuItem();
        MUXGroup = new javax.swing.ButtonGroup();
        Firmware = new javax.swing.ButtonGroup();
        About = new javax.swing.JDialog();
        AppName = new javax.swing.JLabel();
        Version = new javax.swing.JLabel();
        Donate = new javax.swing.JButton();
        Author = new javax.swing.JLabel();
        HomePage = new javax.swing.JButton();
        Author1 = new javax.swing.JLabel();
        ContextMenuESPFileLUA = new javax.swing.JPopupMenu();
        MenuItemESPFileDo = new javax.swing.JMenuItem();
        TerminalSeparator3 = new javax.swing.JPopupMenu.Separator();
        MenuItemESPFileDelete = new javax.swing.JMenuItem();
        buttonGroupLF = new javax.swing.ButtonGroup();
        ContextMenuFileManager = new javax.swing.JPopupMenu();
        ShowFileManager = new javax.swing.JCheckBoxMenuItem();
        HorizontSplit = new javax.swing.JSplitPane();
        LeftBasePane = new javax.swing.JLayeredPane();
        LeftTab = new javax.swing.JTabbedPane();
        NodeMCU = new javax.swing.JPanel();
        TextTab = new javax.swing.JTabbedPane();
        SriptsTab = new javax.swing.JLayeredPane();
        FilesToolBar = new javax.swing.JToolBar();
        ButtonFileNew = new javax.swing.JButton();
        ButtonFileOpen = new javax.swing.JButton();
        ButtonFileReload = new javax.swing.JButton();
        ButtonFileSave = new javax.swing.JButton();
        ButtonFileSaveAll = new javax.swing.JButton();
        ButtonFileClose = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        ButtonUndo = new javax.swing.JButton();
        ButtonRedo = new javax.swing.JButton();
        jSeparator8 = new javax.swing.JToolBar.Separator();
        ButtonCut = new javax.swing.JButton();
        ButtonCopy = new javax.swing.JButton();
        ButtonPaste = new javax.swing.JButton();
        jSeparator6 = new javax.swing.JToolBar.Separator();
        ButtonSendSelected = new javax.swing.JButton();
        ButtonSendLine = new javax.swing.JButton();
        FilesTabbedPane = new javax.swing.JTabbedPane();
        FileLayeredPane = new javax.swing.JLayeredPane();
        TextScroll = new org.fife.ui.rtextarea.RTextScrollPane();
        TextEditor = new org.fife.ui.rsyntaxtextarea.RSyntaxTextArea();
        LeftExtraButtons = new javax.swing.JLayeredPane();
        FileDo1 = new javax.swing.JButton();
        FileCompile = new javax.swing.JButton();
        FileSaveCompileDoLC = new javax.swing.JButton();
        FileUploadBin = new javax.swing.JButton();
        FileCompileDoLC = new javax.swing.JButton();
        Busy = new javax.swing.JLabel();
        FilePathLabel = new javax.swing.JLabel();
        ProgressBar = new javax.swing.JProgressBar();
        LeftMainButtons = new javax.swing.JLayeredPane();
        FileSaveESP = new javax.swing.JToggleButton();
        FileSendESP = new javax.swing.JToggleButton();
        FileDo = new javax.swing.JButton();
        FilesUpload = new javax.swing.JButton();
        NodeMCUCommands = new javax.swing.JLayeredPane();
        CommandsMicroPython = new javax.swing.JLayeredPane();
        CommandsNodeMCU = new javax.swing.JLayeredPane();
        cmdNodeRestart = new javax.swing.JButton();
        cmdTimerStop = new javax.swing.JButton();
        cmdNodeChipID = new javax.swing.JButton();
        TimerNumber = new javax.swing.JComboBox();
        cmdNodeHeap = new javax.swing.JButton();
        cmdListFiles = new javax.swing.JButton();
        cmdNodeSleep = new javax.swing.JButton();
        MicroPythonCommandsTab = new javax.swing.JTabbedPane();
        MicroPythonCommandsWiFi = new javax.swing.JLayeredPane();
        MicroPythonSSID = new javax.swing.JTextField();
        cmdMicroPythonStaConnect = new javax.swing.JButton();
        MicroPythonPASS = new javax.swing.JTextField();
        MicroPythonRemoteHost = new javax.swing.JTextField();
        MicroPythonRemotePort = new javax.swing.JTextField();
        cmdMicroPythonSendToHost = new javax.swing.JButton();
        MicroPythonRemoteData = new javax.swing.JTextField();
        cmdMicroPythonScan = new javax.swing.JButton();
        MicroPythonCommandsGPIO = new javax.swing.JLayeredPane();
        MicroPythonGPIO0_1 = new javax.swing.JButton();
        MicroPythonGPIO0_0 = new javax.swing.JButton();
        MicroPythonGPIO0 = new javax.swing.JButton();
        MicroPythonGPIO2_1 = new javax.swing.JButton();
        MicroPythonGPIO2_0 = new javax.swing.JButton();
        MicroPythonGPIO2 = new javax.swing.JButton();
        MicroPythonGPIO4_1 = new javax.swing.JButton();
        MicroPythonGPIO4_0 = new javax.swing.JButton();
        MicroPythonGPIO4 = new javax.swing.JButton();
        MicroPythonGPIO5_1 = new javax.swing.JButton();
        MicroPythonGPIO5_0 = new javax.swing.JButton();
        MicroPythonGPIO5 = new javax.swing.JButton();
        MicroPythonGPIO9_1 = new javax.swing.JButton();
        MicroPythonGPIO9_0 = new javax.swing.JButton();
        MicroPythonGPIO9 = new javax.swing.JButton();
        MicroPythonGPIO10_1 = new javax.swing.JButton();
        MicroPythonGPIO10_0 = new javax.swing.JButton();
        MicroPythonGPIO10 = new javax.swing.JButton();
        MicroPythonGPIO12_1 = new javax.swing.JButton();
        MicroPythonGPIO12_0 = new javax.swing.JButton();
        MicroPythonGPIO12 = new javax.swing.JButton();
        MicroPythonGPIO13_1 = new javax.swing.JButton();
        MicroPythonGPIO13_0 = new javax.swing.JButton();
        MicroPythonGPIO13 = new javax.swing.JButton();
        MicroPythonGPIO14_1 = new javax.swing.JButton();
        MicroPythonGPIO14_0 = new javax.swing.JButton();
        MicroPythonGPIO14 = new javax.swing.JButton();
        MicroPythonGPIO15_1 = new javax.swing.JButton();
        MicroPythonGPIO15_0 = new javax.swing.JButton();
        MicroPythonGPIO15 = new javax.swing.JButton();
        MicroPythonGPIO16_1 = new javax.swing.JButton();
        MicroPythonGPIO16_0 = new javax.swing.JButton();
        MicroPythonGPIO16 = new javax.swing.JButton();
        NodeMCUSnippets = new javax.swing.JLayeredPane();
        LeftSnippetsPane = new javax.swing.JLayeredPane();
        SnippetEdit0 = new javax.swing.JButton();
        SnippetEdit1 = new javax.swing.JButton();
        SnippetEdit2 = new javax.swing.JButton();
        SnippetEdit3 = new javax.swing.JButton();
        SnippetEdit4 = new javax.swing.JButton();
        SnippetEdit5 = new javax.swing.JButton();
        SnippetEdit6 = new javax.swing.JButton();
        SnippetEdit7 = new javax.swing.JButton();
        SnippetEdit8 = new javax.swing.JButton();
        SnippetEdit9 = new javax.swing.JButton();
        SnippetEdit10 = new javax.swing.JButton();
        SnippetEdit11 = new javax.swing.JButton();
        SnippetEdit12 = new javax.swing.JButton();
        SnippetEdit13 = new javax.swing.JButton();
        SnippetEdit14 = new javax.swing.JButton();
        SnippetEdit15 = new javax.swing.JButton();
        jLayeredPane4 = new javax.swing.JLayeredPane();
        SnippetTopPane = new javax.swing.JLayeredPane();
        SnippetName = new javax.swing.JTextField();
        SnippetSave = new javax.swing.JButton();
        SnippetRun = new javax.swing.JButton();
        SnippetsBusy = new javax.swing.JLabel();
        SnippetCancelEdit = new javax.swing.JButton();
        Condensed = new javax.swing.JCheckBox();
        SnippetScrollPane = new org.fife.ui.rtextarea.RTextScrollPane();
        SnippetText = new org.fife.ui.rsyntaxtextarea.RSyntaxTextArea();
        NodeMCUSettings = new javax.swing.JLayeredPane();
        OptionsFirmware = new javax.swing.JLayeredPane();
        OptionNodeMCU = new javax.swing.JRadioButton();
        OptionMicroPython = new javax.swing.JRadioButton();
        OptionsOther = new javax.swing.JLayeredPane();
        FileAutoSaveDisk = new javax.swing.JCheckBox();
        FileAutoSaveESP = new javax.swing.JCheckBox();
        FileAutoRun = new javax.swing.JCheckBox();
        EditorThemeLabel = new javax.swing.JLabel();
        EditorTheme = new javax.swing.JComboBox();
        UseExternalEditor = new javax.swing.JCheckBox();
        OptionsFileSendMode = new javax.swing.JLayeredPane();
        DelayLabel = new javax.swing.JLabel();
        Delay = new javax.swing.JSlider();
        AnswerDelayLabel = new javax.swing.JLabel();
        AnswerDelay = new javax.swing.JSlider();
        DumbMode = new javax.swing.JCheckBox();
        LineDelayLabel = new javax.swing.JLabel();
        LineDelay = new javax.swing.JSlider();
        TurboMode = new javax.swing.JCheckBox();
        jLayeredPane2 = new javax.swing.JLayeredPane();
        jLabel1 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        TerminalMaxSize = new javax.swing.JTextField();
        LogMaxSize = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLayeredPane3 = new javax.swing.JLayeredPane();
        CustomPortName = new javax.swing.JTextField();
        UseCustomPortName = new javax.swing.JCheckBox();
        jLabel10 = new javax.swing.JLabel();
        AutodetectFirmware = new javax.swing.JCheckBox();
        CommandEcho = new javax.swing.JCheckBox();
        ATvXX = new javax.swing.JLayeredPane();
        BasicATcommandsPane = new javax.swing.JLayeredPane();
        cmdAT = new javax.swing.JButton();
        AT_Restart = new javax.swing.JButton();
        AT_GMR = new javax.swing.JButton();
        GSLP = new javax.swing.JButton();
        ATE0 = new javax.swing.JButton();
        ATE1 = new javax.swing.JButton();
        UPDATE = new javax.swing.JButton();
        TabAT = new javax.swing.JTabbedPane();
        AT_Station = new javax.swing.JPanel();
        TopWiFiStaFiller = new javax.swing.Box.Filler(new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150));
        WiFiStationPane = new javax.swing.JLayeredPane();
        cmdGetCWJAP = new javax.swing.JButton();
        cmdSetCWJAP = new javax.swing.JButton();
        SSID = new javax.swing.JTextField();
        PASS = new javax.swing.JTextField();
        cmdSetCWQAP = new javax.swing.JButton();
        cmdGetCIPSTAMAC = new javax.swing.JButton();
        cmdSetCIPSTAMAC = new javax.swing.JButton();
        MAC = new javax.swing.JFormattedTextField();
        cmdGetCIPSTA = new javax.swing.JButton();
        cmdSetCIPSTA = new javax.swing.JButton();
        StationIP = new javax.swing.JTextField();
        PingIP = new javax.swing.JTextField();
        cmdSetPING = new javax.swing.JButton();
        AT_SoftAP = new javax.swing.JLayeredPane();
        WiFisoftAPPane = new javax.swing.JLayeredPane();
        cmdSetCWSAP = new javax.swing.JButton();
        cmdGetCWSAP = new javax.swing.JButton();
        cmdGetCIPAPMAC = new javax.swing.JButton();
        cmdGetCWLIF = new javax.swing.JButton();
        SSIDsoftAP = new javax.swing.JTextField();
        PASSsoftAP = new javax.swing.JTextField();
        cmdGetCIPAP = new javax.swing.JButton();
        cmdSetCIPAPMAC = new javax.swing.JButton();
        MAC1 = new javax.swing.JFormattedTextField();
        encryption = new javax.swing.JComboBox();
        channel = new javax.swing.JComboBox();
        softAPIP = new javax.swing.JTextField();
        cmdSetCIPAP = new javax.swing.JButton();
        TopWiFiAPFiller = new javax.swing.Box.Filler(new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150));
        AT_Client = new javax.swing.JPanel();
        TopWiFiStaFiller1 = new javax.swing.Box.Filler(new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150));
        TCPclientBottomPane = new javax.swing.JLayeredPane();
        common = new javax.swing.JPanel();
        conn_id = new javax.swing.JComboBox();
        single = new javax.swing.JRadioButton();
        multi = new javax.swing.JRadioButton();
        jLabel4 = new javax.swing.JLabel();
        cmdGetCIPSTART = new javax.swing.JButton();
        UDP = new javax.swing.JLayeredPane();
        udp_local_port = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        udp_mode = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        remote_address = new javax.swing.JTextField();
        remote_port = new javax.swing.JTextField();
        protocol = new javax.swing.JComboBox();
        cmdSetCIPSTART = new javax.swing.JButton();
        jScrollData = new javax.swing.JScrollPane();
        data = new javax.swing.JTextArea();
        cmdCIPSEND = new javax.swing.JButton();
        cmdCIPSENDinteractive = new javax.swing.JButton();
        cmdSetCIPCLOSE = new javax.swing.JButton();
        AT_Server = new javax.swing.JPanel();
        TCPServerTopFiller = new javax.swing.Box.Filler(new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150), new java.awt.Dimension(457, 150));
        TCPServerBottomPane = new javax.swing.JLayeredPane();
        cmdGetCIPMODE = new javax.swing.JButton();
        cmdSetCIPMODE0 = new javax.swing.JButton();
        cmdSetCIPMODE1 = new javax.swing.JButton();
        cmdSetCIPSERVER = new javax.swing.JButton();
        ServerMode = new javax.swing.JComboBox();
        jLabel5 = new javax.swing.JLabel();
        ServerPort = new javax.swing.JTextField();
        cmdGetCIPSTO = new javax.swing.JButton();
        cmdSetCIPSTO = new javax.swing.JButton();
        ServerTimeout = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        TCP_common = new javax.swing.JLayeredPane();
        cmdGetCIPSTATUS = new javax.swing.JButton();
        cmdGetCIPMUX = new javax.swing.JButton();
        cmdSetCIPMUX1 = new javax.swing.JButton();
        cmdSetCIPMUX0 = new javax.swing.JButton();
        cmdGetCIFSR = new javax.swing.JButton();
        WiFi_common = new javax.swing.JLayeredPane();
        cmdGetHelpCWMODE = new javax.swing.JButton();
        cmdSetCWMODE1 = new javax.swing.JButton();
        cmdGetCWMODE = new javax.swing.JButton();
        cmdSetCWMODE2 = new javax.swing.JButton();
        cmdSetCWLAP = new javax.swing.JButton();
        cmdSetCWMODE3 = new javax.swing.JButton();
        DHCP = new javax.swing.JComboBox();
        DHCPmode = new javax.swing.JComboBox();
        cmdSetCWDHCP = new javax.swing.JButton();
        RN2483 = new javax.swing.JLayeredPane();
        RN2483jTab = new javax.swing.JTabbedPane();
        MacPane = new javax.swing.JScrollPane();
        LoRaMAC = new javax.swing.JLayeredPane();
        MacCommon = new javax.swing.JLayeredPane();
        cmdMacSetAdrOn = new javax.swing.JButton();
        cmdMacSetDR = new javax.swing.JButton();
        cmdMacSetPwrIdx = new javax.swing.JButton();
        cmdMacGetStatus = new javax.swing.JButton();
        cmdMacSetAdrOff = new javax.swing.JButton();
        cmdMacGetAdr = new javax.swing.JButton();
        MacDR = new javax.swing.JTextField();
        MacPower = new javax.swing.JTextField();
        cmdMacGetDR = new javax.swing.JButton();
        cmdMacGetPwrIdx = new javax.swing.JButton();
        SendUnconfirmed = new javax.swing.JLayeredPane();
        cmdMacTX = new javax.swing.JButton();
        MacTxPort = new javax.swing.JTextField();
        MacTxData = new javax.swing.JTextField();
        TxConfirmed = new javax.swing.JComboBox<>();
        jLabel13 = new javax.swing.JLabel();
        RadioPane = new javax.swing.JLayeredPane();
        MacSF = new javax.swing.JComboBox<>();
        jLabel11 = new javax.swing.JLabel();
        RadioRxBandWidth = new javax.swing.JTextField();
        RadioFreq = new javax.swing.JTextField();
        cmdRadiosetRxBw = new javax.swing.JButton();
        cmdRadioSetFreq = new javax.swing.JButton();
        cmdRadioGetSF = new javax.swing.JButton();
        cmdRadioGetBw = new javax.swing.JButton();
        cmdRadioGetRxBw = new javax.swing.JButton();
        cmdRadioGetFreq = new javax.swing.JButton();
        MacBandWidth = new javax.swing.JComboBox<>();
        jLabel12 = new javax.swing.JLabel();
        jLayeredPane1 = new javax.swing.JLayeredPane();
        cmdSysReset = new javax.swing.JButton();
        cmdSysFactoryReset = new javax.swing.JButton();
        cmdSysGetVer = new javax.swing.JButton();
        cmdSysGetHwEui = new javax.swing.JButton();
        ActivationScrollPane = new javax.swing.JScrollPane();
        ActivationPane = new javax.swing.JLayeredPane();
        ABPPane = new javax.swing.JLayeredPane();
        cmdMacSetDevAddr = new javax.swing.JButton();
        cmdMacSetNwkSKey = new javax.swing.JButton();
        cmdMacSetAppSKey = new javax.swing.JButton();
        cmdMacjoinABP = new javax.swing.JButton();
        cmdMacGetDevAddr = new javax.swing.JButton();
        DevAddr = new javax.swing.JTextField();
        NwkSKey = new javax.swing.JTextField();
        AppSKey = new javax.swing.JTextField();
        cmdMacSave = new javax.swing.JButton();
        OTAAPane = new javax.swing.JLayeredPane();
        cmdMacSetDevEui = new javax.swing.JButton();
        cmdMacSetAppEui = new javax.swing.JButton();
        cmdMacSetAppKey = new javax.swing.JButton();
        cmdMacJoinOTAA = new javax.swing.JButton();
        cmdMacGetDevEui = new javax.swing.JButton();
        cmdMacGetAppEui = new javax.swing.JButton();
        DevEUI = new javax.swing.JTextField();
        AppEUI = new javax.swing.JTextField();
        AppKey = new javax.swing.JTextField();
        RightBasePane = new javax.swing.JLayeredPane();
        LEDPanel = new javax.swing.JLayeredPane();
        PortOpenLabel = new javax.swing.JLabel();
        PortCTS = new javax.swing.JLabel();
        PortDTR = new javax.swing.JToggleButton();
        PortRTS = new javax.swing.JToggleButton();
        Open = new javax.swing.JToggleButton();
        Speed = new javax.swing.JComboBox();
        ReScan = new javax.swing.JButton();
        AutoScroll = new javax.swing.JCheckBox();
        Port = new javax.swing.JComboBox<>();
        EOL = new javax.swing.JCheckBox();
        CR = new javax.swing.JCheckBox();
        LF = new javax.swing.JCheckBox();
        DonateSmall = new javax.swing.JButton();
        TerminalOnlyCheckBox = new javax.swing.JCheckBox();
        EditorOnlyCheckBox = new javax.swing.JCheckBox();
        RightBigPane = new javax.swing.JLayeredPane();
        RightFilesSplitPane = new javax.swing.JSplitPane();
        TerminalLogPane = new javax.swing.JLayeredPane();
        RightSplitPane = new javax.swing.JSplitPane();
        TerminalPane = new org.fife.ui.rtextarea.RTextScrollPane();
        Terminal = new org.fife.ui.rsyntaxtextarea.RSyntaxTextArea();
        ScrollLog = new javax.swing.JScrollPane();
        Log = new javax.swing.JTextArea();
        FileManagerScrollPane = new javax.swing.JScrollPane();
        FileManagersLayer = new javax.swing.JLayeredPane();
        NodeFileManagerPane = new javax.swing.JLayeredPane();
        FileFormat = new javax.swing.JButton();
        FileSystemInfo = new javax.swing.JButton();
        FileListReload = new javax.swing.JButton();
        FileAsButton1 = new javax.swing.JButton();
        FileRenamePanel = new javax.swing.JLayeredPane();
        FileRenameLabel = new javax.swing.JLabel();
        FileRename = new javax.swing.JTextField();
        PyFileManagerPane = new javax.swing.JLayeredPane();
        PyListDir = new javax.swing.JButton();
        PyFileAsButton1 = new javax.swing.JButton();
        RightSnippetsPane = new javax.swing.JLayeredPane();
        ButtonSnippet0 = new javax.swing.JButton();
        ButtonSnippet1 = new javax.swing.JButton();
        ButtonSnippet2 = new javax.swing.JButton();
        ButtonSnippet3 = new javax.swing.JButton();
        ButtonSnippet4 = new javax.swing.JButton();
        ButtonSnippet5 = new javax.swing.JButton();
        ButtonSnippet6 = new javax.swing.JButton();
        ButtonSnippet7 = new javax.swing.JButton();
        ButtonSnippet8 = new javax.swing.JButton();
        ButtonSnippet9 = new javax.swing.JButton();
        ButtonSnippet10 = new javax.swing.JButton();
        ButtonSnippet11 = new javax.swing.JButton();
        ButtonSnippet12 = new javax.swing.JButton();
        ButtonSnippet13 = new javax.swing.JButton();
        ButtonSnippet14 = new javax.swing.JButton();
        ButtonSnippet15 = new javax.swing.JButton();
        RightExtraButtons = new javax.swing.JLayeredPane();
        NodeHeap = new javax.swing.JButton();
        NodeInfo = new javax.swing.JButton();
        NodeChipID = new javax.swing.JButton();
        NodeFlashID = new javax.swing.JButton();
        NodeReset = new javax.swing.JButton();
        RightBottomPane = new javax.swing.JLayeredPane();
        Command = new javax.swing.JComboBox<>();
        SendCommand = new javax.swing.JButton();
        MainMenuBar = new javax.swing.JMenuBar();
        MenuFile = new javax.swing.JMenu();
        MenuItemFileNew = new javax.swing.JMenuItem();
        MenuItemFileOpen = new javax.swing.JMenuItem();
        MenuItemFileReload = new javax.swing.JMenuItem();
        MenuItemFileSave = new javax.swing.JMenuItem();
        MenuItemFileSaveAs = new javax.swing.JMenuItem();
        MenuItemFileSaveAll = new javax.swing.JMenuItem();
        MenuItemFileClose = new javax.swing.JMenuItem();
        jSeparatorFileMenu = new javax.swing.JPopupMenu.Separator();
        MenuItemFileSaveESP = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        MenuItemFileSendESP = new javax.swing.JMenuItem();
        jMenuItem7 = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JPopupMenu.Separator();
        MenuItemFileDo = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        MenuItemFileRemoveESP = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        MenuItemFileExit = new javax.swing.JMenuItem();
        MenuEdit = new javax.swing.JMenu();
        MenuItemEditUndo = new javax.swing.JMenuItem();
        MenuItemEditRedo = new javax.swing.JMenuItem();
        jSeparator7 = new javax.swing.JPopupMenu.Separator();
        MenuItemEditCut = new javax.swing.JMenuItem();
        MenuItemEditCopy = new javax.swing.JMenuItem();
        MenuItemEditPaste = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JPopupMenu.Separator();
        MenuItemEditSendSelected = new javax.swing.JMenuItem();
        MenuItemEditSendLine = new javax.swing.JMenuItem();
        MenuESP = new javax.swing.JMenu();
        MenuItemESPReset = new javax.swing.JMenuItem();
        MenuItemESPFormat = new javax.swing.JMenuItem();
        MenuView = new javax.swing.JMenu();
        AlwaysOnTop = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewLog = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewClearLog = new javax.swing.JMenuItem();
        MenuItemViewClearTerminal = new javax.swing.JMenuItem();
        jSeparator9 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewTerminalOnly = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewEditorOnly = new javax.swing.JCheckBoxMenuItem();
        jSeparator18 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewToolbar = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewLeftExtra = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewSnippets = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewFileManager = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewRightExtra = new javax.swing.JCheckBoxMenuItem();
        MenuItemViewDonate = new javax.swing.JCheckBoxMenuItem();
        jSeparator13 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewTermFontInc = new javax.swing.JMenuItem();
        MenuItemViewTermFontDec = new javax.swing.JMenuItem();
        jSeparator10 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewEditorFontInc = new javax.swing.JMenuItem();
        MenuItemViewEditorFontDec = new javax.swing.JMenuItem();
        jSeparator11 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewLogFontInc = new javax.swing.JMenuItem();
        MenuItemViewLogFontDec = new javax.swing.JMenuItem();
        jSeparator12 = new javax.swing.JPopupMenu.Separator();
        MenuItemViewFontDefault = new javax.swing.JMenuItem();
        jSeparator17 = new javax.swing.JPopupMenu.Separator();
        MenuLinks = new javax.swing.JMenu();
        MenuItemLinksMicroPythonDoc = new javax.swing.JMenuItem();
        MenuItemLinksNodeMCUdoc = new javax.swing.JMenuItem();
        jSeparator15 = new javax.swing.JPopupMenu.Separator();
        MenuItemLinksBuyDevBoard = new javax.swing.JMenuItem();
        MenuItemLinksBuyESP8266 = new javax.swing.JMenuItem();
        MenuItemLinksBuyESD12 = new javax.swing.JMenuItem();
        MenuItemLinksBuyOther = new javax.swing.JMenuItem();
        jSeparator16 = new javax.swing.JPopupMenu.Separator();
        MenuItemLinksIoTmanager = new javax.swing.JMenuItem();
        jSeparator19 = new javax.swing.JPopupMenu.Separator();
        MenuItemLinksESPlorerForumEn = new javax.swing.JMenuItem();
        MenuItemLinksESPlorerForumRu = new javax.swing.JMenuItem();
        MenuItemLinksESPlorerLatest = new javax.swing.JMenuItem();
        MenuItemLinksESPlorerSource = new javax.swing.JMenuItem();
        MenuItemLinksESPlorerHome = new javax.swing.JMenuItem();
        jSeparator20 = new javax.swing.JPopupMenu.Separator();
        MenuItemLinksDonate = new javax.swing.JMenuItem();
        MenuHelp = new javax.swing.JMenu();
        MenuItemHelpAbout = new javax.swing.JMenuItem();

        ContextMenuTerminal.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                ContextMenuTerminalPopupMenuWillBecomeVisible(evt);
            }
        });

        MenuItemTerminalClear.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F2, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemTerminalClear.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/terminal_clear.png"))); // NOI18N
        MenuItemTerminalClear.setText("清除");
        MenuItemTerminalClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalClearActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalClear);

        MenuItemTerminalCopy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemTerminalCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/copy.png"))); // NOI18N
        MenuItemTerminalCopy.setText("复制");
        MenuItemTerminalCopy.setEnabled(false);
        MenuItemTerminalCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalCopyActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalCopy);
        ContextMenuTerminal.add(TerminalSeparator1);

        MenuItemTerminalFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemTerminalFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemTerminalFontInc.setText("增大字体");
        MenuItemTerminalFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalFontIncActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalFontInc);

        MenuItemTerminalFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemTerminalFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemTerminalFontDec.setText("减小字体");
        MenuItemTerminalFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalFontDecActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalFontDec);
        ContextMenuTerminal.add(TerminalSeparator2);

        MenuItemTerminalReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/reset.png"))); // NOI18N
        MenuItemTerminalReset.setText("重启ESP模块");
        MenuItemTerminalReset.setToolTipText("发送RESET命令(固件依赖)");
        MenuItemTerminalReset.setEnabled(false);
        MenuItemTerminalReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalResetActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalReset);

        MenuItemTerminalFormat.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file manager (delete).png"))); // NOI18N
        MenuItemTerminalFormat.setText("格式化ESP");
        MenuItemTerminalFormat.setToolTipText("删除ESP闪存内存中的所有文件");
        MenuItemTerminalFormat.setEnabled(false);
        MenuItemTerminalFormat.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemTerminalFormatActionPerformed(evt);
            }
        });
        ContextMenuTerminal.add(MenuItemTerminalFormat);

        MenuItemEditorUndo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditorUndo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/undo1.png"))); // NOI18N
        MenuItemEditorUndo.setText("撤销");
        MenuItemEditorUndo.setEnabled(false);
        MenuItemEditorUndo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorUndoActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorUndo);

        MenuItemEditorRedo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, 0));
        MenuItemEditorRedo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/redo1.png"))); // NOI18N
        MenuItemEditorRedo.setText("重做");
        MenuItemEditorRedo.setEnabled(false);
        MenuItemEditorRedo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorRedoActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorRedo);
        ContextMenuEditor.add(EditorSeparator1);

        MenuItemEditorSendSelected.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditorSendSelected.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/send_selected.png"))); // NOI18N
        MenuItemEditorSendSelected.setText("发送块至ESP");
        MenuItemEditorSendSelected.setToolTipText("将选定的片段发送到ESP");
        MenuItemEditorSendSelected.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorSendSelectedActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorSendSelected);

        MenuItemEditorSendLine.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditorSendLine.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/run_line.png"))); // NOI18N
        MenuItemEditorSendLine.setText("发送行至ESP");
        MenuItemEditorSendLine.setToolTipText("将当前行发送至ESP");
        MenuItemEditorSendLine.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorSendLineActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorSendLine);
        ContextMenuEditor.add(EditorSeparator);

        MenuItemEditorCut.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditorCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/cut.png"))); // NOI18N
        MenuItemEditorCut.setText("剪切");
        MenuItemEditorCut.setEnabled(false);
        MenuItemEditorCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorCutActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorCut);

        MenuItemEditorCopy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditorCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/copy.png"))); // NOI18N
        MenuItemEditorCopy.setText("复制");
        MenuItemEditorCopy.setEnabled(false);
        MenuItemEditorCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorCopyActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorCopy);

        MenuItemEditorPaste.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditorPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/paste.png"))); // NOI18N
        MenuItemEditorPaste.setText("粘贴");
        MenuItemEditorPaste.setEnabled(false);
        MenuItemEditorPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorPasteActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorPaste);
        ContextMenuEditor.add(EditorSeparator2);

        MenuItemEditorFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditorFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemEditorFontInc.setText("增大字体");
        MenuItemEditorFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorFontIncActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorFontInc);

        MenuItemEditorFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditorFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemEditorFontDec.setText("减小字体");
        MenuItemEditorFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditorFontDecActionPerformed(evt);
            }
        });
        ContextMenuEditor.add(MenuItemEditorFontDec);

        MenuItemLogClear.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemLogClear.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/backup_delete.png"))); // NOI18N
        MenuItemLogClear.setText("清除日志");
        MenuItemLogClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLogClearActionPerformed(evt);
            }
        });
        ContextMenuLog.add(MenuItemLogClear);

        MenuItemLogClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemLogClose.setText("隐藏日志");
        MenuItemLogClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLogCloseActionPerformed(evt);
            }
        });
        ContextMenuLog.add(MenuItemLogClose);
        ContextMenuLog.add(LogSeparator);

        MenuItemLogFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.ALT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemLogFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemLogFontInc.setText("增大字体");
        MenuItemLogFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLogFontIncActionPerformed(evt);
            }
        });
        ContextMenuLog.add(MenuItemLogFontInc);

        MenuItemLogFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.ALT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemLogFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemLogFontDec.setText("减小字体");
        MenuItemLogFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLogFontDecActionPerformed(evt);
            }
        });
        ContextMenuLog.add(MenuItemLogFontDec);

        About.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        About.setTitle("关于");
        About.setIconImage(null);
        About.setMinimumSize(new java.awt.Dimension(406, 250));
        About.setModalityType(java.awt.Dialog.ModalityType.DOCUMENT_MODAL);
        About.setResizable(false);
        About.addWindowFocusListener(new java.awt.event.WindowFocusListener() {
            public void windowGainedFocus(java.awt.event.WindowEvent evt) {
            }
            public void windowLostFocus(java.awt.event.WindowEvent evt) {
                AboutWindowLostFocus(evt);
            }
        });
        About.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                AboutFocusLost(evt);
            }
        });

        AppName.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        AppName.setText("ESPlorer");
        AppName.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        Version.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        Version.setText(VERSION);
        Version.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        Donate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/donate.gif"))); // NOI18N
        Donate.setToolTipText("如果你想让ESPlorer的作者一次性捐赠，你可以使用PayPal使它快速和容易。");
        Donate.setMaximumSize(new java.awt.Dimension(200, 55));
        Donate.setMinimumSize(new java.awt.Dimension(200, 55));
        Donate.setPreferredSize(new java.awt.Dimension(200, 55));
        Donate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DonateActionPerformed(evt);
            }
        });

        Author.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        Author.setText("由维克多·布鲁茨基 （4refr0nt） - 汉化：Minuy");
        Author.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        HomePage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/wifi.png"))); // NOI18N
        HomePage.setText("查看主页");
        HomePage.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
        HomePage.setMaximumSize(new java.awt.Dimension(200, 55));
        HomePage.setMinimumSize(new java.awt.Dimension(200, 55));
        HomePage.setPreferredSize(new java.awt.Dimension(200, 55));
        HomePage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                HomePageActionPerformed(evt);
            }
        });

        Author1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        Author1.setText("4refr0nt@gmail.com");
        Author1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout AboutLayout = new javax.swing.GroupLayout(About.getContentPane());
        About.getContentPane().setLayout(AboutLayout);
        AboutLayout.setHorizontalGroup(
            AboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(Author, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(AppName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(Version, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(AboutLayout.createSequentialGroup()
                .addComponent(Donate, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(HomePage, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(Author1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        AboutLayout.setVerticalGroup(
            AboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(AboutLayout.createSequentialGroup()
                .addContainerGap(44, Short.MAX_VALUE)
                .addComponent(AppName, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(Version)
                .addGap(18, 18, 18)
                .addComponent(Author)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(Author1)
                .addGap(24, 24, 24)
                .addGroup(AboutLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(Donate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(HomePage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        ContextMenuESPFileLUA.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                ContextMenuESPFileLUAPopupMenuWillBecomeVisible(evt);
            }
        });

        MenuItemESPFileDo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/play.png"))); // NOI18N
        MenuItemESPFileDo.setText("运行文件");
        MenuItemESPFileDo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemESPFileDoActionPerformed(evt);
            }
        });
        ContextMenuESPFileLUA.add(MenuItemESPFileDo);
        ContextMenuESPFileLUA.add(TerminalSeparator3);

        MenuItemESPFileDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file_remove.png"))); // NOI18N
        MenuItemESPFileDelete.setText("删除文件");
        MenuItemESPFileDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemESPFileDeleteActionPerformed(evt);
            }
        });
        ContextMenuESPFileLUA.add(MenuItemESPFileDelete);

        ShowFileManager.setSelected(true);
        ShowFileManager.setText("显示/隐藏文件管理面板");
        ShowFileManager.setToolTipText("查看视图以启用");
        ShowFileManager.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                ShowFileManagerItemStateChanged(evt);
            }
        });
        ContextMenuFileManager.add(ShowFileManager);

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("ESPlorer");
        setAutoRequestFocus(false);
        setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        setLocationByPlatform(true);
        setName("ESPlorer"); // NOI18N
        addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                formFocusGained(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addWindowFocusListener(new java.awt.event.WindowFocusListener() {
            public void windowGainedFocus(java.awt.event.WindowEvent evt) {
                formWindowGainedFocus(evt);
            }
            public void windowLostFocus(java.awt.event.WindowEvent evt) {
            }
        });
        addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                formPropertyChange(evt);
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        HorizontSplit.setDividerLocation(621);
        HorizontSplit.setMinimumSize(new java.awt.Dimension(100, 100));
        HorizontSplit.setPreferredSize(new java.awt.Dimension(768, 567));

        LeftBasePane.setOpaque(true);

        LeftTab.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        LeftTab.setAlignmentX(0.0F);
        LeftTab.setAlignmentY(0.0F);
        LeftTab.setAutoscrolls(true);
        LeftTab.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        LeftTab.setMinimumSize(new java.awt.Dimension(100, 100));
        LeftTab.setOpaque(true);
        LeftTab.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                LeftTabStateChanged(evt);
            }
        });

        NodeMCU.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        NodeMCU.setMinimumSize(new java.awt.Dimension(100, 100));
        NodeMCU.setPreferredSize(new java.awt.Dimension(461, 537));
        NodeMCU.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                NodeMCUFocusGained(evt);
            }
        });
        NodeMCU.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                NodeMCUComponentShown(evt);
            }
        });

        TextTab.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        TextTab.setComponentPopupMenu(ContextMenuEditor);
        TextTab.setMinimumSize(new java.awt.Dimension(462, 365));
        TextTab.setOpaque(true);
        TextTab.setPreferredSize(new java.awt.Dimension(462, 365));
        TextTab.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                TextTabStateChanged(evt);
            }
        });

        SriptsTab.setMinimumSize(new java.awt.Dimension(460, 350));
        SriptsTab.setOpaque(true);

        FilesToolBar.setFloatable(false);
        FilesToolBar.setRollover(true);
        FilesToolBar.setAlignmentY(0.5F);
        FilesToolBar.setMaximumSize(new java.awt.Dimension(1000, 40));
        FilesToolBar.setMinimumSize(new java.awt.Dimension(321, 40));
        FilesToolBar.setPreferredSize(new java.awt.Dimension(321, 40));

        ButtonFileNew.setAction(MenuItemFileNew.getAction());
        ButtonFileNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/document.png"))); // NOI18N
        ButtonFileNew.setText("新建");
        ButtonFileNew.setToolTipText("新建一个文件");
        ButtonFileNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileNew.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileNew.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileNew.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileNewActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileNew);

        ButtonFileOpen.setAction(MenuItemFileOpen.getAction());
        ButtonFileOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/folder open.png"))); // NOI18N
        ButtonFileOpen.setText("打开");
        ButtonFileOpen.setToolTipText("从磁盘打开文件");
        ButtonFileOpen.setHideActionText(true);
        ButtonFileOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileOpen.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileOpen.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileOpen.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileOpenActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileOpen);

        ButtonFileReload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/refresh.png"))); // NOI18N
        ButtonFileReload.setText("重载");
        ButtonFileReload.setToolTipText("从磁盘重新加载文件(用于外部编辑器)");
        ButtonFileReload.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileReload.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileReload.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileReload.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileReload.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileReload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileReloadActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileReload);

        ButtonFileSave.setAction(MenuItemFileSave.getAction());
        ButtonFileSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save.png"))); // NOI18N
        ButtonFileSave.setText("保存");
        ButtonFileSave.setToolTipText("将文件保存到磁盘");
        ButtonFileSave.setHideActionText(true);
        ButtonFileSave.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileSave.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileSave.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileSave.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileSaveActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileSave);

        ButtonFileSaveAll.setAction(MenuItemFileSave.getAction());
        ButtonFileSaveAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save_all.png"))); // NOI18N
        ButtonFileSaveAll.setText("全存");
        ButtonFileSaveAll.setToolTipText("将所有打开的文件保存到磁盘");
        ButtonFileSaveAll.setEnabled(false);
        ButtonFileSaveAll.setFocusable(false);
        ButtonFileSaveAll.setHideActionText(true);
        ButtonFileSaveAll.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileSaveAll.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileSaveAll.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileSaveAll.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileSaveAll.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileSaveAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileSaveAllActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileSaveAll);

        ButtonFileClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/folder closed.png"))); // NOI18N
        ButtonFileClose.setText("关闭");
        ButtonFileClose.setToolTipText("关闭文件");
        ButtonFileClose.setHideActionText(true);
        ButtonFileClose.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonFileClose.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonFileClose.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonFileClose.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonFileClose.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonFileClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonFileCloseActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonFileClose);
        FilesToolBar.add(jSeparator1);

        ButtonUndo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/undo1.png"))); // NOI18N
        ButtonUndo.setText("撤销");
        ButtonUndo.setToolTipText("撤销上一个操作");
        ButtonUndo.setEnabled(false);
        ButtonUndo.setFocusable(false);
        ButtonUndo.setHideActionText(true);
        ButtonUndo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonUndo.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonUndo.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonUndo.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonUndo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonUndo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonUndoActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonUndo);

        ButtonRedo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/redo1.png"))); // NOI18N
        ButtonRedo.setText("重做");
        ButtonRedo.setToolTipText("重做上一个操作");
        ButtonRedo.setEnabled(false);
        ButtonRedo.setFocusable(false);
        ButtonRedo.setHideActionText(true);
        ButtonRedo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonRedo.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonRedo.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonRedo.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonRedo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonRedo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonRedoActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonRedo);
        FilesToolBar.add(jSeparator8);

        ButtonCut.setAction(MenuItemEditCut.getAction());
        ButtonCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/cut.png"))); // NOI18N
        ButtonCut.setText("剪切");
        ButtonCut.setToolTipText("剪切");
        ButtonCut.setEnabled(false);
        ButtonCut.setHideActionText(true);
        ButtonCut.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonCut.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonCut.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonCut.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonCut.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonCutActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonCut);

        ButtonCopy.setAction(MenuItemEditCopy.getAction());
        ButtonCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/copy.png"))); // NOI18N
        ButtonCopy.setText("复制");
        ButtonCopy.setToolTipText("复制");
        ButtonCopy.setEnabled(false);
        ButtonCopy.setHideActionText(true);
        ButtonCopy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonCopy.setMargin(new java.awt.Insets(2, 2, 2, 2));
        ButtonCopy.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonCopy.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonCopy.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonCopy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonCopyActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonCopy);

        ButtonPaste.setAction(MenuItemEditPaste.getAction());
        ButtonPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/paste.png"))); // NOI18N
        ButtonPaste.setText("粘贴");
        ButtonPaste.setToolTipText("粘贴");
        ButtonPaste.setEnabled(false);
        ButtonPaste.setHideActionText(true);
        ButtonPaste.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonPaste.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonPaste.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonPaste.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonPaste.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonPasteActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonPaste);
        FilesToolBar.add(jSeparator6);

        ButtonSendSelected.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/send_selected.png"))); // NOI18N
        ButtonSendSelected.setText("发块");
        ButtonSendSelected.setToolTipText("将选定的块发送到ESP");
        ButtonSendSelected.setHideActionText(true);
        ButtonSendSelected.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonSendSelected.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonSendSelected.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonSendSelected.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonSendSelected.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonSendSelected.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSendSelectedActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonSendSelected);

        ButtonSendLine.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/run_line.png"))); // NOI18N
        ButtonSendLine.setText("发行");
        ButtonSendLine.setToolTipText("将当前的行发送到ESP");
        ButtonSendLine.setFocusable(false);
        ButtonSendLine.setHideActionText(true);
        ButtonSendLine.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ButtonSendLine.setMaximumSize(new java.awt.Dimension(40, 40));
        ButtonSendLine.setMinimumSize(new java.awt.Dimension(40, 40));
        ButtonSendLine.setPreferredSize(new java.awt.Dimension(40, 40));
        ButtonSendLine.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ButtonSendLine.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSendLineActionPerformed(evt);
            }
        });
        FilesToolBar.add(ButtonSendLine);
        FilesTabbedPane.setOpaque(true);
        FilesTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                FilesTabbedPaneStateChanged(evt);
            }
        });

        FileLayeredPane.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                FileLayeredPaneFocusGained(evt);
            }
        });

        TextScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        TextScroll.setViewportBorder(javax.swing.BorderFactory.createEtchedBorder());
        TextScroll.setFoldIndicatorEnabled(true);
        TextScroll.setLineNumbersEnabled(true);
        TextScroll.setViewportView(TextEditor);

        TextEditor.setColumns(20);
        TextEditor.setRows(5);
        TextEditor.setTabSize(4);
        TextEditor.setCodeFoldingEnabled(true);
        TextEditor.setDragEnabled(false);
        TextEditor.setFadeCurrentLineHighlight(true);
        TextEditor.setPaintMarkOccurrencesBorder(true);
        TextEditor.setPaintMatchedBracketPair(true);
        TextEditor.setPopupMenu(ContextMenuEditor);
        TextEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LUA);
        TextEditor.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                TextEditorCaretUpdate(evt);
            }
        });
        TextEditor.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                TextEditorFocusGained(evt);
            }
        });
        TextEditor.addActiveLineRangeListener(new org.fife.ui.rsyntaxtextarea.ActiveLineRangeListener() {
            public void activeLineRangeChanged(org.fife.ui.rsyntaxtextarea.ActiveLineRangeEvent evt) {
                TextEditorActiveLineRangeChanged(evt);
            }
        });
        TextEditor.addInputMethodListener(new java.awt.event.InputMethodListener() {
            public void caretPositionChanged(java.awt.event.InputMethodEvent evt) {
                TextEditorCaretPositionChanged(evt);
            }
            public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) {
                TextEditorInputMethodTextChanged(evt);
            }
        });
        TextEditor.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                TextEditorKeyTyped(evt);
            }
        });
        TextScroll.setViewportView(TextEditor);

        FileLayeredPane.setLayer(TextScroll, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout FileLayeredPaneLayout = new javax.swing.GroupLayout(FileLayeredPane);
        FileLayeredPane.setLayout(FileLayeredPaneLayout);
        FileLayeredPaneLayout.setHorizontalGroup(
            FileLayeredPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TextScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 526, Short.MAX_VALUE)
        );
        FileLayeredPaneLayout.setVerticalGroup(
            FileLayeredPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TextScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
        );

        FilesTabbedPane.addTab("NewFile", FileLayeredPane);

        LeftExtraButtons.setEnabled(false);
        LeftExtraButtons.setOpaque(true);
        LeftExtraButtons.setPreferredSize(new java.awt.Dimension(431, 66));
        LeftExtraButtons.setLayout(new java.awt.FlowLayout());

        FileDo1.setText("保存并运行");
        FileDo1.setToolTipText("运行Lua脚本");
        FileDo1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        FileDo1.setIconTextGap(8);
        FileDo1.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileDo1.setMaximumSize(new java.awt.Dimension(127, 30));
        FileDo1.setMinimumSize(new java.awt.Dimension(127, 30));
        FileDo1.setPreferredSize(new java.awt.Dimension(127, 30));
        FileDo1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileDo1ActionPerformed(evt);
            }
        });
        LeftExtraButtons.add(FileDo1);

        FileCompile.setText("保存并编译");
        FileCompile.setToolTipText("重新编译lua脚本并执行lua字节码lc文件");
        FileCompile.setIconTextGap(2);
        FileCompile.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileCompile.setMaximumSize(new java.awt.Dimension(127, 30));
        FileCompile.setMinimumSize(new java.awt.Dimension(127, 30));
        FileCompile.setPreferredSize(new java.awt.Dimension(127, 30));
        FileCompile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileCompileActionPerformed(evt);
            }
        });
        LeftExtraButtons.add(FileCompile);

        FileSaveCompileDoLC.setText("保存编译并运行LC");
        FileSaveCompileDoLC.setIconTextGap(0);
        FileSaveCompileDoLC.setMargin(new java.awt.Insets(2, 0, 2, 0));
        FileSaveCompileDoLC.setMaximumSize(new java.awt.Dimension(127, 30));
        FileSaveCompileDoLC.setMinimumSize(new java.awt.Dimension(127, 30));
        FileSaveCompileDoLC.setPreferredSize(new java.awt.Dimension(127, 30));
        FileSaveCompileDoLC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileSaveCompileDoLCActionPerformed(evt);
            }
        });
        LeftExtraButtons.add(FileSaveCompileDoLC);

        FileUploadBin.setText("另存为初始化文件");
        FileUploadBin.setToolTipText("另存为init.lua到ESP上");
        FileUploadBin.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        FileUploadBin.setIconTextGap(0);
        FileUploadBin.setMargin(new java.awt.Insets(2, 0, 2, 0));
        FileUploadBin.setMaximumSize(new java.awt.Dimension(127, 30));
        FileUploadBin.setMinimumSize(new java.awt.Dimension(127, 30));
        FileUploadBin.setPreferredSize(new java.awt.Dimension(127, 30));
        FileUploadBin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileUploadBinActionPerformed(evt);
            }
        });
        LeftExtraButtons.add(FileUploadBin);

        FileCompileDoLC.setText("全部保存并编译");
        FileCompileDoLC.setActionCommand("Save&CompileAll");
        FileCompileDoLC.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        FileCompileDoLC.setIconTextGap(0);
        FileCompileDoLC.setMargin(new java.awt.Insets(2, 0, 2, 0));
        FileCompileDoLC.setMaximumSize(new java.awt.Dimension(127, 30));
        FileCompileDoLC.setMinimumSize(new java.awt.Dimension(127, 30));
        FileCompileDoLC.setPreferredSize(new java.awt.Dimension(127, 30));
        FileCompileDoLC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileCompileDoLCActionPerformed(evt);
            }
        });
        LeftExtraButtons.add(FileCompileDoLC);

        Busy.setBackground(new java.awt.Color(0, 153, 0));
        Busy.setForeground(new java.awt.Color(255, 255, 255));
        Busy.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        Busy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        Busy.setText("空闲");
        Busy.setOpaque(true);

        FilePathLabel.setText("jLabel1");

        ProgressBar.setOpaque(true);
        ProgressBar.setStringPainted(true);

        LeftMainButtons.setOpaque(true);
        LeftMainButtons.setLayout(new java.awt.FlowLayout());

        FileSaveESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/move.png"))); // NOI18N
        FileSaveESP.setText("保存到ESP");
        FileSaveESP.setToolTipText("发送文件到ESP并保存到闪存");
        FileSaveESP.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileSaveESP.setIconTextGap(8);
        FileSaveESP.setMaximumSize(new java.awt.Dimension(127, 30));
        FileSaveESP.setMinimumSize(new java.awt.Dimension(127, 30));
        FileSaveESP.setPreferredSize(new java.awt.Dimension(127, 30));
        FileSaveESP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileSaveESPActionPerformed(evt);
            }
        });
        LeftMainButtons.add(FileSaveESP);

        FileSendESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/script_send.png"))); // NOI18N
        FileSendESP.setText("发送到ESP");
        FileSendESP.setToolTipText("将文件发送到ESP并“逐行”运行");
        FileSendESP.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileSendESP.setIconTextGap(8);
        FileSendESP.setMaximumSize(new java.awt.Dimension(127, 30));
        FileSendESP.setMinimumSize(new java.awt.Dimension(127, 30));
        FileSendESP.setPreferredSize(new java.awt.Dimension(127, 30));
        FileSendESP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileSendESPActionPerformed(evt);
            }
        });
        LeftMainButtons.add(FileSendESP);

        FileDo.setFont(FileDo.getFont());
        FileDo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/play.png"))); // NOI18N
        FileDo.setText("执行");
        FileDo.setToolTipText("通过“dofile”命令执行lua脚本");
        FileDo.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileDo.setIconTextGap(8);
        FileDo.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileDo.setMaximumSize(new java.awt.Dimension(127, 30));
        FileDo.setMinimumSize(new java.awt.Dimension(127, 30));
        FileDo.setPreferredSize(new java.awt.Dimension(127, 30));
        FileDo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileDoActionPerformed(evt);
            }
        });
        LeftMainButtons.add(FileDo);

        FilesUpload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/uploadLUA.png"))); // NOI18N
        FilesUpload.setText("上传");
        FilesUpload.setToolTipText("从磁盘上传文件到ESP闪存");
        FilesUpload.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FilesUpload.setIconTextGap(8);
        FilesUpload.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FilesUpload.setMaximumSize(new java.awt.Dimension(127, 30));
        FilesUpload.setMinimumSize(new java.awt.Dimension(127, 30));
        FilesUpload.setPreferredSize(new java.awt.Dimension(127, 30));
        FilesUpload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FilesUploadActionPerformed(evt);
            }
        });
        LeftMainButtons.add(FilesUpload);

        SriptsTab.setLayer(FilesToolBar, javax.swing.JLayeredPane.PALETTE_LAYER);
        SriptsTab.setLayer(FilesTabbedPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SriptsTab.setLayer(LeftExtraButtons, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SriptsTab.setLayer(Busy, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SriptsTab.setLayer(FilePathLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SriptsTab.setLayer(ProgressBar, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SriptsTab.setLayer(LeftMainButtons, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout SriptsTabLayout = new javax.swing.GroupLayout(SriptsTab);
        SriptsTab.setLayout(SriptsTabLayout);
        SriptsTabLayout.setHorizontalGroup(
            SriptsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FilesTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addComponent(FilesToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(SriptsTabLayout.createSequentialGroup()
                .addGroup(SriptsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(ProgressBar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, SriptsTabLayout.createSequentialGroup()
                        .addGap(6, 6, 6)
                        .addComponent(Busy, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(FilePathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(LeftExtraButtons, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 531, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(LeftMainButtons, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 531, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
        SriptsTabLayout.setVerticalGroup(
            SriptsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SriptsTabLayout.createSequentialGroup()
                .addComponent(FilesToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(FilesTabbedPane)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(SriptsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Busy)
                    .addComponent(FilePathLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(LeftExtraButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(LeftMainButtons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        FilesTabbedPane.getAccessibleContext().setAccessibleName("New File");

        TextTab.addTab("脚本", SriptsTab);
        SriptsTab.getAccessibleContext().setAccessibleName("Files");

        NodeMCUCommands.setOpaque(true);
        NodeMCUCommands.setLayout(new javax.swing.BoxLayout(NodeMCUCommands, javax.swing.BoxLayout.PAGE_AXIS));

        CommandsMicroPython.setBorder(javax.swing.BorderFactory.createTitledBorder("MicroPython命令"));

        javax.swing.GroupLayout CommandsMicroPythonLayout = new javax.swing.GroupLayout(CommandsMicroPython);
        CommandsMicroPython.setLayout(CommandsMicroPythonLayout);
        CommandsMicroPythonLayout.setHorizontalGroup(
            CommandsMicroPythonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        CommandsMicroPythonLayout.setVerticalGroup(
            CommandsMicroPythonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 73, Short.MAX_VALUE)
        );

        NodeMCUCommands.add(CommandsMicroPython);
        CommandsMicroPython.getAccessibleContext().setAccessibleDescription("");

        CommandsNodeMCU.setBorder(javax.swing.BorderFactory.createTitledBorder("NodeMCU命令"));

        cmdNodeRestart.setToolTipText("给ESP8266发送重启命令");
        cmdNodeRestart.setLabel("重启ESP");
        cmdNodeRestart.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdNodeRestart.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdNodeRestart.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdNodeRestart.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdNodeRestart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdNodeRestartActionPerformed(evt);
            }
        });

        cmdTimerStop.setText("停止计时器");
        cmdTimerStop.setToolTipText("tmr.stop");
        cmdTimerStop.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdTimerStop.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdTimerStop.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdTimerStop.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdTimerStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdTimerStopActionPerformed(evt);
            }
        });

        cmdNodeChipID.setText("芯片 ID");
        cmdNodeChipID.setToolTipText("获取ESP8266芯片身份识标");
        cmdNodeChipID.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdNodeChipID.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdNodeChipID.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdNodeChipID.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdNodeChipID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdNodeChipIDActionPerformed(evt);
            }
        });

        TimerNumber.setMaximumRowCount(7);
        TimerNumber.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0", "1", "2", "3", "4", "5", "6" }));
        TimerNumber.setToolTipText("定时器编号 (0-6)");

        cmdNodeHeap.setText("堆栈");
        cmdNodeHeap.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdNodeHeap.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdNodeHeap.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdNodeHeap.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdNodeHeap.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdNodeHeapActionPerformed(evt);
            }
        });

        cmdListFiles.setText("文件列表");
        cmdListFiles.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdListFiles.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdListFiles.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdListFiles.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdListFiles.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdListFilesActionPerformed(evt);
            }
        });

        cmdNodeSleep.setText("休眠 10000");
        cmdNodeSleep.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdNodeSleep.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdNodeSleep.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdNodeSleep.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdNodeSleep.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdNodeSleepActionPerformed(evt);
            }
        });

        CommandsNodeMCU.setLayer(cmdNodeRestart, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(cmdTimerStop, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(cmdNodeChipID, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(TimerNumber, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(cmdNodeHeap, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(cmdListFiles, javax.swing.JLayeredPane.DEFAULT_LAYER);
        CommandsNodeMCU.setLayer(cmdNodeSleep, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout CommandsNodeMCULayout = new javax.swing.GroupLayout(CommandsNodeMCU);
        CommandsNodeMCU.setLayout(CommandsNodeMCULayout);
        CommandsNodeMCULayout.setHorizontalGroup(
            CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(CommandsNodeMCULayout.createSequentialGroup()
                .addGroup(CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(CommandsNodeMCULayout.createSequentialGroup()
                        .addComponent(cmdNodeRestart, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cmdNodeChipID, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(CommandsNodeMCULayout.createSequentialGroup()
                        .addComponent(cmdTimerStop, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(TimerNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(CommandsNodeMCULayout.createSequentialGroup()
                        .addComponent(cmdNodeHeap, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cmdNodeSleep, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(cmdListFiles, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
        CommandsNodeMCULayout.setVerticalGroup(
            CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(CommandsNodeMCULayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdNodeChipID, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdNodeRestart, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdNodeHeap, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdNodeSleep, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(CommandsNodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdListFiles, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdTimerStop, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(TimerNumber))
                .addContainerGap())
        );

        NodeMCUCommands.add(CommandsNodeMCU);

        MicroPythonSSID.setText("WIFI名称");
        MicroPythonSSID.setToolTipText("输入WIFI名称");
        MicroPythonSSID.setMaximumSize(new java.awt.Dimension(100, 23));
        MicroPythonSSID.setMinimumSize(new java.awt.Dimension(100, 23));
        MicroPythonSSID.setPreferredSize(new java.awt.Dimension(100, 23));
        MicroPythonSSID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSSIDActionPerformed(evt);
            }
        });
        MicroPythonSSID.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                MicroPythonSSIDFocusGained(evt);
            }
        });

        cmdMicroPythonStaConnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect3.png"))); // NOI18N
        cmdMicroPythonStaConnect.setText("连接到热点");
        cmdMicroPythonStaConnect.setToolTipText("连接WiFi接入点");
        cmdMicroPythonStaConnect.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMicroPythonStaConnect.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonStaConnect.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonStaConnect.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonStaConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMicroPythonStaConnectActionPerformed(evt);
            }
        });

        MicroPythonPASS.setText("密码");
        MicroPythonPASS.setToolTipText("输入WIFI密码");
        MicroPythonPASS.setMaximumSize(new java.awt.Dimension(104, 23));
        MicroPythonPASS.setMinimumSize(new java.awt.Dimension(104, 23));
        MicroPythonPASS.setPreferredSize(new java.awt.Dimension(104, 23));
        MicroPythonPASS.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonPASSActionPerformed(evt);
            }
        });
        MicroPythonPASS.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                MicroPythonPASSFocusGained(evt);
            }
        });

        MicroPythonRemoteHost.setText("micropython.org");
        MicroPythonRemoteHost.setToolTipText("远端主机名");

        MicroPythonRemotePort.setText("80");
        MicroPythonRemotePort.setToolTipText("远端主机端口");

        cmdMicroPythonSendToHost.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect3.png"))); // NOI18N
        cmdMicroPythonSendToHost.setText("连接并发送");
        cmdMicroPythonSendToHost.setToolTipText("作为客户端启动连接");
        cmdMicroPythonSendToHost.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMicroPythonSendToHostActionPerformed(evt);
            }
        });

        MicroPythonRemoteData.setText("GET / HTTP/1.1\\r\\nHost: micropython.org\\r\\n\\r\\n");
        MicroPythonRemoteData.setToolTipText("发送数据");

        cmdMicroPythonScan.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/search again.png"))); // NOI18N
        cmdMicroPythonScan.setText("扫描网络");
        cmdMicroPythonScan.setToolTipText("列出所有可用的WiFi接入点");
        cmdMicroPythonScan.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMicroPythonScan.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonScan.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonScan.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMicroPythonScan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMicroPythonScanActionPerformed(evt);
            }
        });

        MicroPythonCommandsWiFi.setLayer(MicroPythonSSID, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(cmdMicroPythonStaConnect, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(MicroPythonPASS, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(MicroPythonRemoteHost, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(MicroPythonRemotePort, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(cmdMicroPythonSendToHost, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(MicroPythonRemoteData, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MicroPythonCommandsWiFi.setLayer(cmdMicroPythonScan, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout MicroPythonCommandsWiFiLayout = new javax.swing.GroupLayout(MicroPythonCommandsWiFi);
        MicroPythonCommandsWiFi.setLayout(MicroPythonCommandsWiFiLayout);
        MicroPythonCommandsWiFiLayout.setHorizontalGroup(
            MicroPythonCommandsWiFiLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(MicroPythonCommandsWiFiLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(MicroPythonCommandsWiFiLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmdMicroPythonStaConnect, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, MicroPythonCommandsWiFiLayout.createSequentialGroup()
                        .addComponent(MicroPythonSSID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(MicroPythonPASS, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(MicroPythonCommandsWiFiLayout.createSequentialGroup()
                        .addComponent(MicroPythonRemoteHost, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(MicroPythonRemotePort))
                    .addComponent(cmdMicroPythonSendToHost, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(MicroPythonRemoteData, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMicroPythonScan, javax.swing.GroupLayout.PREFERRED_SIZE, 206, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        MicroPythonCommandsWiFiLayout.setVerticalGroup(
            MicroPythonCommandsWiFiLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(MicroPythonCommandsWiFiLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(MicroPythonCommandsWiFiLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(MicroPythonSSID, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MicroPythonPASS, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMicroPythonScan, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMicroPythonStaConnect, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(MicroPythonCommandsWiFiLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(MicroPythonRemoteHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MicroPythonRemotePort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MicroPythonRemoteData, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMicroPythonSendToHost)
                .addContainerGap(293, Short.MAX_VALUE))
        );

        MicroPythonCommandsTab.addTab(" WiFi ", MicroPythonCommandsWiFi);

        MicroPythonCommandsGPIO.setLayout(new java.awt.GridLayout(11, 3));

        MicroPythonGPIO0_1.setText("GPIO0 -> 1");
        MicroPythonGPIO0_1.setActionCommand("0");
        MicroPythonGPIO0_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO0_1);

        MicroPythonGPIO0_0.setText("GPIO0 -> 0");
        MicroPythonGPIO0_0.setActionCommand("0");
        MicroPythonGPIO0_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO0_0);

        MicroPythonGPIO0.setText("GPIO0 ?");
        MicroPythonGPIO0.setActionCommand("0");
        MicroPythonGPIO0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO0);

        MicroPythonGPIO2_1.setText("GPIO2 -> 1");
        MicroPythonGPIO2_1.setActionCommand("2");
        MicroPythonGPIO2_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO2_1);

        MicroPythonGPIO2_0.setText("GPIO2 -> 0");
        MicroPythonGPIO2_0.setActionCommand("2");
        MicroPythonGPIO2_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO2_0);

        MicroPythonGPIO2.setText("GPIO2 ?");
        MicroPythonGPIO2.setActionCommand("2");
        MicroPythonGPIO2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO2);

        MicroPythonGPIO4_1.setText("GPIO4 -> 1");
        MicroPythonGPIO4_1.setActionCommand("4");
        MicroPythonGPIO4_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO4_1);

        MicroPythonGPIO4_0.setText("GPIO4 -> 0");
        MicroPythonGPIO4_0.setActionCommand("4");
        MicroPythonGPIO4_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO4_0);

        MicroPythonGPIO4.setText("GPIO4 ?");
        MicroPythonGPIO4.setActionCommand("4");
        MicroPythonGPIO4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO4);

        MicroPythonGPIO5_1.setText("GPIO5 -> 1");
        MicroPythonGPIO5_1.setActionCommand("5");
        MicroPythonGPIO5_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO5_1);

        MicroPythonGPIO5_0.setText("GPIO5 -> 0");
        MicroPythonGPIO5_0.setActionCommand("5");
        MicroPythonGPIO5_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO5_0);

        MicroPythonGPIO5.setText("GPIO5 ?");
        MicroPythonGPIO5.setActionCommand("5");
        MicroPythonGPIO5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO5);

        MicroPythonGPIO9_1.setText("GPIO9 -> 1");
        MicroPythonGPIO9_1.setActionCommand("9");
        MicroPythonGPIO9_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO9_1);

        MicroPythonGPIO9_0.setText("GPIO9 -> 0");
        MicroPythonGPIO9_0.setActionCommand("9");
        MicroPythonGPIO9_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO9_0);

        MicroPythonGPIO9.setText("GPIO9 ?");
        MicroPythonGPIO9.setActionCommand("9");
        MicroPythonGPIO9.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO9);

        MicroPythonGPIO10_1.setText("GPIO10 -> 1");
        MicroPythonGPIO10_1.setActionCommand("10");
        MicroPythonGPIO10_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO10_1);

        MicroPythonGPIO10_0.setText("GPIO10 -> 0");
        MicroPythonGPIO10_0.setActionCommand("10");
        MicroPythonGPIO10_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO10_0);

        MicroPythonGPIO10.setText("GPIO10 ?");
        MicroPythonGPIO10.setActionCommand("10");
        MicroPythonGPIO10.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO10);

        MicroPythonGPIO12_1.setText("GPIO12 -> 1");
        MicroPythonGPIO12_1.setActionCommand("12");
        MicroPythonGPIO12_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO12_1);

        MicroPythonGPIO12_0.setText("GPIO12 -> 0");
        MicroPythonGPIO12_0.setActionCommand("12");
        MicroPythonGPIO12_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO12_0);

        MicroPythonGPIO12.setText("GPIO12 ?");
        MicroPythonGPIO12.setActionCommand("12");
        MicroPythonGPIO12.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO12);

        MicroPythonGPIO13_1.setText("GPIO13 -> 1");
        MicroPythonGPIO13_1.setActionCommand("13");
        MicroPythonGPIO13_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO13_1);

        MicroPythonGPIO13_0.setText("GPIO13 -> 0");
        MicroPythonGPIO13_0.setActionCommand("13");
        MicroPythonGPIO13_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO13_0);

        MicroPythonGPIO13.setText("GPIO13 ?");
        MicroPythonGPIO13.setActionCommand("13");
        MicroPythonGPIO13.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO13);

        MicroPythonGPIO14_1.setText("GPIO14 -> 1");
        MicroPythonGPIO14_1.setActionCommand("14");
        MicroPythonGPIO14_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO14_1);

        MicroPythonGPIO14_0.setText("GPIO14 -> 0");
        MicroPythonGPIO14_0.setActionCommand("14");
        MicroPythonGPIO14_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO14_0);

        MicroPythonGPIO14.setText("GPIO14 ?");
        MicroPythonGPIO14.setActionCommand("14");
        MicroPythonGPIO14.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO14);

        MicroPythonGPIO15_1.setText("GPIO15 -> 1");
        MicroPythonGPIO15_1.setActionCommand("15");
        MicroPythonGPIO15_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO15_1);

        MicroPythonGPIO15_0.setText("GPIO15 -> 0");
        MicroPythonGPIO15_0.setActionCommand("15");
        MicroPythonGPIO15_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO15_0);

        MicroPythonGPIO15.setText("GPIO15 ?");
        MicroPythonGPIO15.setActionCommand("15");
        MicroPythonGPIO15.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO15);

        MicroPythonGPIO16_1.setText("GPIO16 -> 1");
        MicroPythonGPIO16_1.setActionCommand("16");
        MicroPythonGPIO16_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOHigh(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO16_1);

        MicroPythonGPIO16_0.setText("GPIO16 -> 0");
        MicroPythonGPIO16_0.setActionCommand("16");
        MicroPythonGPIO16_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonSetGPIOLow(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO16_0);

        MicroPythonGPIO16.setText("GPIO16 ?");
        MicroPythonGPIO16.setActionCommand("16");
        MicroPythonGPIO16.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MicroPythonGetGPIOLevel(evt);
            }
        });
        MicroPythonCommandsGPIO.add(MicroPythonGPIO16);

        MicroPythonCommandsTab.addTab(" 引脚 ", MicroPythonCommandsGPIO);

        NodeMCUCommands.add(MicroPythonCommandsTab);

        TextTab.addTab("命令", NodeMCUCommands);

        NodeMCUSnippets.setLayout(new javax.swing.BoxLayout(NodeMCUSnippets, javax.swing.BoxLayout.LINE_AXIS));

        LeftSnippetsPane.setMaximumSize(new java.awt.Dimension(150, 32767));
        LeftSnippetsPane.setLayout(new java.awt.GridLayout(16, 1));

        SnippetEdit0.setText("片段编辑 0");
        SnippetEdit0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit0ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit0);

        SnippetEdit1.setText("片段编辑 1");
        SnippetEdit1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit1ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit1);

        SnippetEdit2.setText("片段编辑 2");
        SnippetEdit2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit2ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit2);

        SnippetEdit3.setText("片段编辑 3");
        SnippetEdit3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit3ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit3);

        SnippetEdit4.setText("片段编辑 4");
        SnippetEdit4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit4ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit4);

        SnippetEdit5.setText("片段编辑 5");
        SnippetEdit5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit5ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit5);

        SnippetEdit6.setText("片段编辑 6");
        SnippetEdit6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit6ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit6);

        SnippetEdit7.setText("片段编辑 7");
        SnippetEdit7.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit7ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit7);

        SnippetEdit8.setText("片段编辑 8");
        SnippetEdit8.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit8ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit8);

        SnippetEdit9.setText("片段编辑 9");
        SnippetEdit9.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit9ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit9);

        SnippetEdit10.setFont(SnippetEdit10.getFont());
        SnippetEdit10.setText("片段编辑 10");
        SnippetEdit10.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit10ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit10);

        SnippetEdit11.setFont(SnippetEdit11.getFont());
        SnippetEdit11.setText("片段编辑 11");
        SnippetEdit11.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit11ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit11);

        SnippetEdit12.setText("片段编辑 12");
        SnippetEdit12.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit12ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit12);

        SnippetEdit13.setText("片段编辑 13");
        SnippetEdit13.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit13ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit13);

        SnippetEdit14.setText("片段编辑 14");
        SnippetEdit14.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit14ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit14);

        SnippetEdit15.setText("片段编辑 15");
        SnippetEdit15.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetEdit15ActionPerformed(evt);
            }
        });
        LeftSnippetsPane.add(SnippetEdit15);

        NodeMCUSnippets.add(LeftSnippetsPane);

        jLayeredPane4.setLayout(new javax.swing.BoxLayout(jLayeredPane4, javax.swing.BoxLayout.PAGE_AXIS));

        SnippetName.setEnabled(false);

        SnippetSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save.png"))); // NOI18N
        SnippetSave.setText("保存");
        SnippetSave.setToolTipText("保存片段到磁盘上");
        SnippetSave.setEnabled(false);
        SnippetSave.setMargin(new java.awt.Insets(2, 2, 2, 2));
        SnippetSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetSaveActionPerformed(evt);
            }
        });

        SnippetRun.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/server1_start.png"))); // NOI18N
        SnippetRun.setText("运行");
        SnippetRun.setToolTipText("运行片段");
        SnippetRun.setEnabled(false);
        SnippetRun.setMargin(new java.awt.Insets(2, 2, 2, 2));
        SnippetRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetRunActionPerformed(evt);
            }
        });

        SnippetsBusy.setBackground(new java.awt.Color(0, 153, 0));
        SnippetsBusy.setForeground(new java.awt.Color(255, 255, 255));
        SnippetsBusy.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        SnippetsBusy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        SnippetsBusy.setText("空闲");
        SnippetsBusy.setOpaque(true);

        SnippetCancelEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/abort.png"))); // NOI18N
        SnippetCancelEdit.setText("取消");
        SnippetCancelEdit.setToolTipText("取消编辑并清除编辑器窗口");
        SnippetCancelEdit.setEnabled(false);
        SnippetCancelEdit.setMargin(new java.awt.Insets(2, 2, 2, 2));
        SnippetCancelEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SnippetCancelEditActionPerformed(evt);
            }
        });

        Condensed.setText("精简执行");
        Condensed.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                CondensedItemStateChanged(evt);
            }
        });

        SnippetTopPane.setLayer(SnippetName, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SnippetTopPane.setLayer(SnippetSave, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SnippetTopPane.setLayer(SnippetRun, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SnippetTopPane.setLayer(SnippetsBusy, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SnippetTopPane.setLayer(SnippetCancelEdit, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SnippetTopPane.setLayer(Condensed, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout SnippetTopPaneLayout = new javax.swing.GroupLayout(SnippetTopPane);
        SnippetTopPane.setLayout(SnippetTopPaneLayout);
        SnippetTopPaneLayout.setHorizontalGroup(
            SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SnippetTopPaneLayout.createSequentialGroup()
                .addGroup(SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(SnippetTopPaneLayout.createSequentialGroup()
                        .addComponent(SnippetSave)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(SnippetCancelEdit))
                    .addComponent(SnippetName))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(SnippetsBusy, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(SnippetTopPaneLayout.createSequentialGroup()
                        .addComponent(SnippetRun, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(Condensed)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        SnippetTopPaneLayout.setVerticalGroup(
            SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SnippetTopPaneLayout.createSequentialGroup()
                .addGroup(SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(SnippetName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SnippetsBusy))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(SnippetTopPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(SnippetSave)
                    .addComponent(SnippetRun)
                    .addComponent(SnippetCancelEdit)
                    .addComponent(Condensed)))
        );

        jLayeredPane4.add(SnippetTopPane);

        SnippetScrollPane.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        SnippetScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        SnippetScrollPane.setEnabled(false);
        SnippetScrollPane.setLineNumbersEnabled(true);

        SnippetText.setEditable(false);
        SnippetText.setColumns(20);
        SnippetText.setRows(5);
        SnippetText.setEnabled(false);
        SnippetScrollPane.setViewportView(SnippetText);

        jLayeredPane4.add(SnippetScrollPane);

        NodeMCUSnippets.add(jLayeredPane4);

        TextTab.addTab("片段", NodeMCUSnippets);

        NodeMCUSettings.setAutoscrolls(true);
        NodeMCUSettings.setOpaque(true);

        OptionsFirmware.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "选择固件", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Monospaced", 0, 12))); // NOI18N
        OptionsFirmware.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N

        Firmware.add(OptionNodeMCU);
        OptionNodeMCU.setSelected(true);
        OptionNodeMCU.setText("NodeMCU");
        OptionNodeMCU.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                OptionNodeMCUStateChanged(evt);
            }
        });
        OptionNodeMCU.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                OptionNodeMCUItemStateChanged(evt);
            }
        });

        Firmware.add(OptionMicroPython);
        OptionMicroPython.setText("MicroPython");
        OptionMicroPython.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                OptionMicroPythonStateChanged(evt);
            }
        });
        OptionMicroPython.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                OptionMicroPythonItemStateChanged(evt);
            }
        });

        OptionsFirmware.setLayer(OptionNodeMCU, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFirmware.setLayer(OptionMicroPython, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout OptionsFirmwareLayout = new javax.swing.GroupLayout(OptionsFirmware);
        OptionsFirmware.setLayout(OptionsFirmwareLayout);
        OptionsFirmwareLayout.setHorizontalGroup(
            OptionsFirmwareLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(OptionNodeMCU, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(OptionMicroPython, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        OptionsFirmwareLayout.setVerticalGroup(
            OptionsFirmwareLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(OptionsFirmwareLayout.createSequentialGroup()
                .addComponent(OptionNodeMCU)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(OptionMicroPython)
                .addContainerGap())
        );

        OptionsOther.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "其他", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Monospaced", 0, 12))); // NOI18N

        FileAutoSaveDisk.setSelected(true);
        FileAutoSaveDisk.setText("在保存到ESP之前将文件自动保存到磁盘");
        FileAutoSaveDisk.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileAutoSaveDisk.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        FileAutoSaveDisk.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                FileAutoSaveDiskItemStateChanged(evt);
            }
        });

        FileAutoSaveESP.setSelected(true);
        FileAutoSaveESP.setText("将文件保存到磁盘后自动保存到ESP");
        FileAutoSaveESP.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileAutoSaveESP.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        FileAutoSaveESP.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                FileAutoSaveESPItemStateChanged(evt);
            }
        });

        FileAutoRun.setText("文件保存到ESP后自动运行");
        FileAutoRun.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileAutoRun.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        FileAutoRun.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                FileAutoRunItemStateChanged(evt);
            }
        });

        EditorThemeLabel.setText("编辑颜色主题");

        EditorTheme.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "默认", "深色", "Eclipse", "IDEA", "Visual Studio", "默认亮色" }));
        EditorTheme.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EditorThemeActionPerformed(evt);
            }
        });

        UseExternalEditor.setText("使用外部编辑器");
        UseExternalEditor.setToolTipText("使用外部编辑器后所有文件将以只读模式打开");
        UseExternalEditor.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        UseExternalEditor.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        UseExternalEditor.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                UseExternalEditorItemStateChanged(evt);
            }
        });

        OptionsOther.setLayer(FileAutoSaveDisk, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsOther.setLayer(FileAutoSaveESP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsOther.setLayer(FileAutoRun, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsOther.setLayer(EditorThemeLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsOther.setLayer(EditorTheme, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsOther.setLayer(UseExternalEditor, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout OptionsOtherLayout = new javax.swing.GroupLayout(OptionsOther);
        OptionsOther.setLayout(OptionsOtherLayout);
        OptionsOtherLayout.setHorizontalGroup(
            OptionsOtherLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FileAutoSaveDisk, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(FileAutoSaveESP, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(OptionsOtherLayout.createSequentialGroup()
                .addComponent(EditorThemeLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(EditorTheme, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addComponent(UseExternalEditor, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(FileAutoRun, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        OptionsOtherLayout.setVerticalGroup(
            OptionsOtherLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(OptionsOtherLayout.createSequentialGroup()
                .addComponent(FileAutoSaveDisk, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(1, 1, 1)
                .addComponent(FileAutoSaveESP, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(UseExternalEditor)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(OptionsOtherLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(EditorThemeLabel)
                    .addComponent(EditorTheme, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(FileAutoRun)
                .addContainerGap(39, Short.MAX_VALUE))
        );

        OptionsFileSendMode.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "发送", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Monospaced", 0, 12))); // NOI18N

        DelayLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        DelayLabel.setText("回应后延迟 = 0毫秒");
        DelayLabel.setToolTipText("这不是你所知道的“线路延迟”，是从ESP应答到发送新数据之间的延迟");

        Delay.setMajorTickSpacing(500);
        Delay.setMaximum(1000);
        Delay.setMinorTickSpacing(100);
        Delay.setPaintLabels(true);
        Delay.setPaintTicks(true);
        Delay.setSnapToTicks(true);
        Delay.setToolTipText("从ESP应答到发送新数据之间的延迟");
        Delay.setValue(0);
        Delay.setAlignmentY(1.0F);
        Delay.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                DelayStateChanged(evt);
            }
        });

        AnswerDelayLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        AnswerDelayLabel.setText("回应超时时间 = 3 秒");
        AnswerDelayLabel.setToolTipText("我们等ESP8266的答复有多久");

        AnswerDelay.setMajorTickSpacing(5);
        AnswerDelay.setMaximum(10);
        AnswerDelay.setMinorTickSpacing(1);
        AnswerDelay.setPaintLabels(true);
        AnswerDelay.setPaintTicks(true);
        AnswerDelay.setSnapToTicks(true);
        AnswerDelay.setToolTipText("等待固件应答的最大时间");
        AnswerDelay.setValue(3);
        AnswerDelay.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                AnswerDelayStateChanged(evt);
            }
        });

        DumbMode.setText("“开环模式”，从不检查应答");
        DumbMode.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                DumbModeItemStateChanged(evt);
            }
        });

        LineDelayLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        LineDelayLabel.setText("“开环模式”的线路延迟 = 200毫秒");
        LineDelayLabel.setToolTipText("正如你所知，这是通常的“线路延迟”。");

        LineDelay.setMajorTickSpacing(500);
        LineDelay.setMaximum(1000);
        LineDelay.setMinorTickSpacing(100);
        LineDelay.setPaintLabels(true);
        LineDelay.setPaintTicks(true);
        LineDelay.setSnapToTicks(true);
        LineDelay.setToolTipText("线间固定延迟");
        LineDelay.setValue(200);
        LineDelay.setAlignmentY(1.0F);
        LineDelay.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                LineDelayStateChanged(evt);
            }
        });

        TurboMode.setText("“兼容模式”");
        TurboMode.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                TurboModeItemStateChanged(evt);
            }
        });
        TurboMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                TurboModeActionPerformed(evt);
            }
        });

        OptionsFileSendMode.setLayer(DelayLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(Delay, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(AnswerDelayLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(AnswerDelay, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(DumbMode, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(LineDelayLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(LineDelay, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OptionsFileSendMode.setLayer(TurboMode, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout OptionsFileSendModeLayout = new javax.swing.GroupLayout(OptionsFileSendMode);
        OptionsFileSendMode.setLayout(OptionsFileSendModeLayout);
        OptionsFileSendModeLayout.setHorizontalGroup(
            OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(OptionsFileSendModeLayout.createSequentialGroup()
                .addGroup(OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(OptionsFileSendModeLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(LineDelay, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(OptionsFileSendModeLayout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addGroup(OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(TurboMode, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE)
                                .addComponent(DelayLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addGroup(OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(DumbMode, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(Delay, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(AnswerDelayLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(AnswerDelay, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(LineDelayLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        OptionsFileSendModeLayout.setVerticalGroup(
            OptionsFileSendModeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(OptionsFileSendModeLayout.createSequentialGroup()
                .addComponent(TurboMode)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(DelayLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(Delay, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(AnswerDelayLabel)
                .addGap(1, 1, 1)
                .addComponent(AnswerDelay, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(DumbMode)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(LineDelayLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(LineDelay, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(33, Short.MAX_VALUE))
        );

        jLayeredPane2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "数据回显", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Monospaced", 0, 12))); // NOI18N

        jLabel1.setText("终端");
        jLabel1.setPreferredSize(new java.awt.Dimension(40, 20));

        jLabel7.setText("日志");
        jLabel7.setPreferredSize(new java.awt.Dimension(17, 23));

        TerminalMaxSize.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        TerminalMaxSize.setText("100");
        TerminalMaxSize.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                TerminalMaxSizeFocusLost(evt);
            }
        });

        LogMaxSize.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        LogMaxSize.setText("10");
        LogMaxSize.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                LogMaxSizeFocusLost(evt);
            }
        });
        LogMaxSize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                LogMaxSizeActionPerformed(evt);
            }
        });

        jLabel8.setText("kb");

        jLabel9.setText("kb");

        jLayeredPane2.setLayer(jLabel1, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane2.setLayer(jLabel7, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane2.setLayer(TerminalMaxSize, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane2.setLayer(LogMaxSize, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane2.setLayer(jLabel8, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane2.setLayer(jLabel9, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout jLayeredPane2Layout = new javax.swing.GroupLayout(jLayeredPane2);
        jLayeredPane2.setLayout(jLayeredPane2Layout);
        jLayeredPane2Layout.setHorizontalGroup(
            jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jLayeredPane2Layout.createSequentialGroup()
                .addGroup(jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(TerminalMaxSize, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE)
                    .addComponent(LogMaxSize))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel8)
                    .addComponent(jLabel9))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jLayeredPane2Layout.setVerticalGroup(
            jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jLayeredPane2Layout.createSequentialGroup()
                .addGroup(jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(TerminalMaxSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jLayeredPane2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(LogMaxSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9)))
        );

        jLayeredPane3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "串口", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Monospaced", 0, 12))); // NOI18N

        CustomPortName.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        CustomPortName.setText("/dev/AnySerialDevice");
        CustomPortName.setEnabled(false);
        CustomPortName.setMinimumSize(new java.awt.Dimension(50, 19));
        CustomPortName.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                CustomPortNameFocusLost(evt);
            }
        });

        UseCustomPortName.setText("使用自定义串口名称");
        UseCustomPortName.setToolTipText("使用自定义串口名称(自动扫描将被禁用)");
        UseCustomPortName.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                UseCustomPortNameActionPerformed(evt);
            }
        });

        jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel10.setText("(自动扫描将被禁用)");
        jLabel10.setPreferredSize(new java.awt.Dimension(17, 23));

        AutodetectFirmware.setText("自动侦测固件");
        AutodetectFirmware.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                AutodetectFirmwareItemStateChanged(evt);
            }
        });

        CommandEcho.setSelected(true);
        CommandEcho.setText("命令回显");
        CommandEcho.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                CommandEchoItemStateChanged(evt);
            }
        });

        jLayeredPane3.setLayer(CustomPortName, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane3.setLayer(UseCustomPortName, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane3.setLayer(jLabel10, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane3.setLayer(AutodetectFirmware, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane3.setLayer(CommandEcho, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout jLayeredPane3Layout = new javax.swing.GroupLayout(jLayeredPane3);
        jLayeredPane3.setLayout(jLayeredPane3Layout);
        jLayeredPane3Layout.setHorizontalGroup(
            jLayeredPane3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(UseCustomPortName, javax.swing.GroupLayout.DEFAULT_SIZE, 161, Short.MAX_VALUE)
            .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(CustomPortName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(AutodetectFirmware, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(CommandEcho, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        jLayeredPane3Layout.setVerticalGroup(
            jLayeredPane3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jLayeredPane3Layout.createSequentialGroup()
                .addComponent(UseCustomPortName)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(CustomPortName, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(AutodetectFirmware)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(CommandEcho)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        NodeMCUSettings.setLayer(OptionsFirmware, javax.swing.JLayeredPane.DEFAULT_LAYER);
        NodeMCUSettings.setLayer(OptionsOther, javax.swing.JLayeredPane.DEFAULT_LAYER);
        NodeMCUSettings.setLayer(OptionsFileSendMode, javax.swing.JLayeredPane.DEFAULT_LAYER);
        NodeMCUSettings.setLayer(jLayeredPane2, javax.swing.JLayeredPane.DEFAULT_LAYER);
        NodeMCUSettings.setLayer(jLayeredPane3, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout NodeMCUSettingsLayout = new javax.swing.GroupLayout(NodeMCUSettings);
        NodeMCUSettings.setLayout(NodeMCUSettingsLayout);
        NodeMCUSettingsLayout.setHorizontalGroup(
            NodeMCUSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(NodeMCUSettingsLayout.createSequentialGroup()
                .addGroup(NodeMCUSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(OptionsOther)
                    .addComponent(OptionsFirmware)
                    .addComponent(OptionsFileSendMode))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(NodeMCUSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLayeredPane2)
                    .addComponent(jLayeredPane3))
                .addContainerGap(65, Short.MAX_VALUE))
        );
        NodeMCUSettingsLayout.setVerticalGroup(
            NodeMCUSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(NodeMCUSettingsLayout.createSequentialGroup()
                .addGroup(NodeMCUSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(NodeMCUSettingsLayout.createSequentialGroup()
                        .addComponent(OptionsFirmware, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(OptionsOther, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(NodeMCUSettingsLayout.createSequentialGroup()
                        .addComponent(jLayeredPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLayeredPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(OptionsFileSendMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 119, Short.MAX_VALUE))
        );

        OptionsFirmware.getAccessibleContext().setAccessibleDescription("");

        TextTab.addTab("设置", new javax.swing.ImageIcon(getClass().getResource("/resources/settings2.png")), NodeMCUSettings, "文件传送设置"); // NOI18N

        javax.swing.GroupLayout NodeMCULayout = new javax.swing.GroupLayout(NodeMCU);
        NodeMCU.setLayout(NodeMCULayout);
        NodeMCULayout.setHorizontalGroup(
            NodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TextTab, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE)
        );
        NodeMCULayout.setVerticalGroup(
            NodeMCULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TextTab, javax.swing.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE)
        );

        TextTab.getAccessibleContext().setAccessibleName("NewFile");

        LeftTab.addTab(" NodeMCU & MicroPython ", NodeMCU);

        ATvXX.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        BasicATcommandsPane.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED), "基础AT指令", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        BasicATcommandsPane.setToolTipText("基础AT指令");
        BasicATcommandsPane.setMaximumSize(new java.awt.Dimension(445, 50));
        BasicATcommandsPane.setMinimumSize(new java.awt.Dimension(445, 50));
        BasicATcommandsPane.setOpaque(true);
        BasicATcommandsPane.setLayout(new java.awt.FlowLayout());

        cmdAT.setText("AT");
        cmdAT.setToolTipText("超级简单的命令 \"AT\"");
        cmdAT.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdATActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(cmdAT);

        AT_Restart.setText("RST");
        AT_Restart.setToolTipText("重启");
        AT_Restart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AT_RestartActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(AT_Restart);

        AT_GMR.setText("GMR");
        AT_GMR.setToolTipText("获取版本信息");
        AT_GMR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AT_GMRActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(AT_GMR);

        GSLP.setText("GSLP");
        GSLP.setToolTipText("5秒进入深度睡眠模式");
        GSLP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                GSLPActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(GSLP);

        ATE0.setText("ATE0");
        ATE0.setToolTipText("关闭回显");
        ATE0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ATE0ActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(ATE0);

        ATE1.setText("ATE1");
        ATE1.setToolTipText("打开回显");
        ATE1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ATE1ActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(ATE1);

        UPDATE.setText("UPD");
        UPDATE.setToolTipText("发送命令 \"AT+UPDATE\" 来更新固件");
        UPDATE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                UPDATEActionPerformed(evt);
            }
        });
        BasicATcommandsPane.add(UPDATE);

        ATvXX.add(BasicATcommandsPane, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, -1, -1));

        TabAT.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        TabAT.setToolTipText("ESP8266 AT 指令 v0.20");
        TabAT.setAlignmentX(0.0F);
        TabAT.setAlignmentY(0.0F);
        TabAT.setFocusable(false);
        TabAT.setOpaque(true);

        AT_Station.setToolTipText("WiFi 指令");
        AT_Station.setAlignmentX(0.0F);
        AT_Station.setAlignmentY(0.0F);
        AT_Station.setAutoscrolls(true);
        AT_Station.setInheritsPopupMenu(true);
        AT_Station.setMinimumSize(new java.awt.Dimension(0, 130));
        AT_Station.setName(""); // NOI18N
        AT_Station.setOpaque(false);
        AT_Station.setPreferredSize(new java.awt.Dimension(457, 291));
        AT_Station.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                AT_StationFocusGained(evt);
            }
        });
        AT_Station.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                AT_StationComponentShown(evt);
            }
        });

        TopWiFiStaFiller.setOpaque(true);

        WiFiStationPane.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "WiFi配置"));
        WiFiStationPane.setAlignmentX(0.0F);
        WiFiStationPane.setAlignmentY(0.0F);
        WiFiStationPane.setMaximumSize(new java.awt.Dimension(463, 291));
        WiFiStationPane.setMinimumSize(new java.awt.Dimension(463, 291));
        WiFiStationPane.setName(""); // NOI18N
        WiFiStationPane.setOpaque(true);

        cmdGetCWJAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/information.png"))); // NOI18N
        cmdGetCWJAP.setText("CWJAP? - 连接信息");
        cmdGetCWJAP.setToolTipText("查询由ESP8266连接的AP信息");
        cmdGetCWJAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCWJAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCWJAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCWJAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCWJAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCWJAPActionPerformed(evt);
            }
        });

        cmdSetCWJAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect3.png"))); // NOI18N
        cmdSetCWJAP.setText("CWJAP 连接到热点");
        cmdSetCWJAP.setToolTipText("连接WiFi接入点");
        cmdSetCWJAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWJAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWJAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWJAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWJAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWJAPActionPerformed(evt);
            }
        });

        SSID.setText("WIFI名称");
        SSID.setToolTipText("输入WIFI名称");
        SSID.setMaximumSize(new java.awt.Dimension(100, 23));
        SSID.setMinimumSize(new java.awt.Dimension(100, 23));
        SSID.setPreferredSize(new java.awt.Dimension(100, 23));
        SSID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SSIDActionPerformed(evt);
            }
        });
        SSID.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                SSIDFocusGained(evt);
            }
        });

        PASS.setText("WIFI密码");
        PASS.setToolTipText("输入WIFI密码");
        PASS.setMaximumSize(new java.awt.Dimension(104, 23));
        PASS.setMinimumSize(new java.awt.Dimension(104, 23));
        PASS.setPreferredSize(new java.awt.Dimension(104, 23));
        PASS.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PASSActionPerformed(evt);
            }
        });
        PASS.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                PASSFocusGained(evt);
            }
        });

        cmdSetCWQAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/disconnect3.png"))); // NOI18N
        cmdSetCWQAP.setText("CWQAP - 断开热点");
        cmdSetCWQAP.setToolTipText("断开WIFI连接");
        cmdSetCWQAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWQAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWQAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWQAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWQAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWQAPActionPerformed(evt);
            }
        });

        cmdGetCIPSTAMAC.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCIPSTAMAC.setText("CIPSTAMAC? 获取MAC地址");
        cmdGetCIPSTAMAC.setToolTipText("获取模块的MAC地址");
        cmdGetCIPSTAMAC.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPSTAMAC.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTAMAC.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTAMAC.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTAMAC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPSTAMACActionPerformed(evt);
            }
        });

        cmdSetCIPSTAMAC.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/set.png"))); // NOI18N
        cmdSetCIPSTAMAC.setText("CIPSTAMAC= 设置MAC");
        cmdSetCIPSTAMAC.setToolTipText("设置模块的MAC地址");
        cmdSetCIPSTAMAC.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPSTAMAC.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTAMAC.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTAMAC.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTAMAC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPSTAMACActionPerformed(evt);
            }
        });

        try {
            MAC.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("AA:AA:AA:AA:AA:AA")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }
        MAC.setText("FF:FF:FF:FF:FF:FF");
        MAC.setToolTipText("模块MAC地址");
        MAC.setMaximumSize(new java.awt.Dimension(210, 23));
        MAC.setMinimumSize(new java.awt.Dimension(210, 23));
        MAC.setPreferredSize(new java.awt.Dimension(210, 23));

        cmdGetCIPSTA.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCIPSTA.setText("CIPSTA? 获取IP");
        cmdGetCIPSTA.setToolTipText("获取模块的当前IP");
        cmdGetCIPSTA.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPSTA.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTA.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTA.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCIPSTA.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPSTAActionPerformed(evt);
            }
        });

        cmdSetCIPSTA.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/set.png"))); // NOI18N
        cmdSetCIPSTA.setText("CIPSTA= 设置IP");
        cmdSetCIPSTA.setToolTipText("设置模块的IP");
        cmdSetCIPSTA.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPSTA.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTA.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTA.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCIPSTA.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPSTAActionPerformed(evt);
            }
        });

        StationIP.setText("192.168.1.50");
        StationIP.setMaximumSize(new java.awt.Dimension(210, 23));
        StationIP.setMinimumSize(new java.awt.Dimension(210, 23));
        StationIP.setPreferredSize(new java.awt.Dimension(210, 23));

        PingIP.setText("192.168.1.1");
        PingIP.setToolTipText("要ping的节点IP地址或主机名");
        PingIP.setMaximumSize(new java.awt.Dimension(210, 23));
        PingIP.setMinimumSize(new java.awt.Dimension(210, 23));
        PingIP.setPreferredSize(new java.awt.Dimension(210, 23));

        cmdSetPING.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/ping.png"))); // NOI18N
        cmdSetPING.setText("PING= Ping远程节点");
        cmdSetPING.setToolTipText("Ping网络中的一个节点");
        cmdSetPING.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetPING.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetPING.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetPING.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetPING.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetPINGActionPerformed(evt);
            }
        });

        WiFiStationPane.setLayer(cmdGetCWJAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdSetCWJAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(SSID, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(PASS, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdSetCWQAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdGetCIPSTAMAC, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdSetCIPSTAMAC, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(MAC, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdGetCIPSTA, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdSetCIPSTA, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(StationIP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(PingIP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFiStationPane.setLayer(cmdSetPING, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout WiFiStationPaneLayout = new javax.swing.GroupLayout(WiFiStationPane);
        WiFiStationPane.setLayout(WiFiStationPaneLayout);
        WiFiStationPaneLayout.setHorizontalGroup(
            WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(WiFiStationPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(MAC, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdSetCIPSTAMAC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(WiFiStationPaneLayout.createSequentialGroup()
                        .addGroup(WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(cmdGetCWJAP, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdSetCWQAP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(WiFiStationPaneLayout.createSequentialGroup()
                                .addGap(1, 1, 1)
                                .addComponent(cmdGetCIPSTAMAC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(WiFiStationPaneLayout.createSequentialGroup()
                                .addComponent(SSID, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(PASS, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                            .addComponent(cmdSetCWJAP, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(cmdGetCIPSTA, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(StationIP, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdSetCIPSTA, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(PingIP, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdSetPING, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        WiFiStationPaneLayout.setVerticalGroup(
            WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(WiFiStationPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdGetCWJAP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SSID, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(PASS, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(WiFiStationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdSetCWQAP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdSetCWJAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdGetCIPSTAMAC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MAC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetCIPSTAMAC, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdGetCIPSTA, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(StationIP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetCIPSTA, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(PingIP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetPING, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(128, Short.MAX_VALUE))
        );

        WiFiStationPaneLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {cmdGetCIPSTA, cmdGetCWJAP, cmdSetCIPSTA, cmdSetCWQAP});

        WiFiStationPaneLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {MAC, StationIP, cmdGetCIPSTAMAC, cmdSetCIPSTAMAC, cmdSetCWJAP});

        javax.swing.GroupLayout AT_StationLayout = new javax.swing.GroupLayout(AT_Station);
        AT_Station.setLayout(AT_StationLayout);
        AT_StationLayout.setHorizontalGroup(
            AT_StationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TopWiFiStaFiller, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(WiFiStationPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        AT_StationLayout.setVerticalGroup(
            AT_StationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, AT_StationLayout.createSequentialGroup()
                .addComponent(TopWiFiStaFiller, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(WiFiStationPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        TabAT.addTab("WiFi 配置", null, AT_Station, "WiFi AT 命令");
        AT_Station.getAccessibleContext().setAccessibleName("");
        AT_Station.getAccessibleContext().setAccessibleDescription("WiFi AT 命令");

        AT_SoftAP.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                AT_SoftAPFocusGained(evt);
            }
        });
        AT_SoftAP.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                AT_SoftAPComponentShown(evt);
            }
        });

        WiFisoftAPPane.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "WiFi 热点"));
        WiFisoftAPPane.setAlignmentX(0.0F);
        WiFisoftAPPane.setAlignmentY(0.0F);
        WiFisoftAPPane.setMaximumSize(new java.awt.Dimension(463, 291));
        WiFisoftAPPane.setMinimumSize(new java.awt.Dimension(463, 291));
        WiFisoftAPPane.setOpaque(true);

        cmdSetCWSAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/server1_start.png"))); // NOI18N
        cmdSetCWSAP.setText("CWSAP=  配置热点");
        cmdSetCWSAP.setToolTipText("设置热点模式的配置");
        cmdSetCWSAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWSAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWSAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWSAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWSAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWSAPActionPerformed(evt);
            }
        });

        cmdGetCWSAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/information.png"))); // NOI18N
        cmdGetCWSAP.setText("AT+CWSAP? 获取热点配置");
        cmdGetCWSAP.setToolTipText("获取热点模式的配置");
        cmdGetCWSAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCWSAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCWSAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCWSAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCWSAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCWSAPActionPerformed(evt);
            }
        });

        cmdGetCIPAPMAC.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCIPAPMAC.setText("CIPAPMAC 获取热点MAC");
        cmdGetCIPAPMAC.setToolTipText("获得ESP8266热点的MAC地址");
        cmdGetCIPAPMAC.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPAPMAC.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAPMAC.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAPMAC.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAPMAC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPAPMACActionPerformed(evt);
            }
        });

        cmdGetCWLIF.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCWLIF.setText("CWLIF 获取客户端IP");
        cmdGetCWLIF.setToolTipText("获取已连接的客户端IP");
        cmdGetCWLIF.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCWLIF.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCWLIF.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCWLIF.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCWLIF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCWLIFActionPerformed(evt);
            }
        });

        SSIDsoftAP.setText("WIFI名称");
        SSIDsoftAP.setToolTipText("输入WIFI名称");
        SSIDsoftAP.setMaximumSize(new java.awt.Dimension(100, 23));
        SSIDsoftAP.setMinimumSize(new java.awt.Dimension(100, 23));
        SSIDsoftAP.setPreferredSize(new java.awt.Dimension(100, 23));
        SSIDsoftAP.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                SSIDsoftAPFocusGained(evt);
            }
        });
        SSIDsoftAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SSIDsoftAPActionPerformed(evt);
            }
        });

        PASSsoftAP.setText("WIFI密码");
        PASSsoftAP.setToolTipText("输入WIFI密码");
        PASSsoftAP.setMaximumSize(new java.awt.Dimension(104, 23));
        PASSsoftAP.setMinimumSize(new java.awt.Dimension(104, 23));
        PASSsoftAP.setPreferredSize(new java.awt.Dimension(104, 23));
        PASSsoftAP.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                PASSsoftAPFocusGained(evt);
            }
        });
        PASSsoftAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PASSsoftAPActionPerformed(evt);
            }
        });

        cmdGetCIPAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCIPAP.setToolTipText("获取ESP8266热点的IP地址");
        cmdGetCIPAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCIPAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPAPActionPerformed(evt);
            }
        });

        cmdSetCIPAPMAC.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/set.png"))); // NOI18N
        cmdSetCIPAPMAC.setToolTipText("设置热点的MAC");
        cmdSetCIPAPMAC.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPAPMAC.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAPMAC.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAPMAC.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAPMAC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPAPMACActionPerformed(evt);
            }
        });

        try {
            MAC1.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("AA:AA:AA:AA:AA:AA")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }
        MAC1.setText("FF:FF:FF:FF:FF:FF");
        MAC1.setToolTipText("模块的MAC地址");
        MAC1.setMaximumSize(new java.awt.Dimension(2108, 23));
        MAC1.setMinimumSize(new java.awt.Dimension(2108, 23));
        MAC1.setPreferredSize(new java.awt.Dimension(2108, 23));

        encryption.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0 - 开放", "1 - WPA_PSK", "2 - WPA2_PSK", "3 - WPA_WPA2_PSK" }));
        encryption.setSelectedIndex(2);
        encryption.setToolTipText("设置加密类型");
        encryption.setMaximumSize(new java.awt.Dimension(104, 23));
        encryption.setMinimumSize(new java.awt.Dimension(104, 23));
        encryption.setPreferredSize(new java.awt.Dimension(104, 23));

        channel.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        channel.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "channel 1", "channel 2", "channel 3", "channel 4", "channel 5", "channel 6", "channel 7", "channel 8", "channel 9", "channel 10", "channel 11", "channel 12", "channel 13" }));
        channel.setToolTipText("设置热点信道");
        channel.setAlignmentX(0.0F);
        channel.setMaximumSize(new java.awt.Dimension(100, 23));
        channel.setMinimumSize(new java.awt.Dimension(100, 23));
        channel.setPreferredSize(new java.awt.Dimension(100, 23));

        softAPIP.setText("192.168.4.1");
        softAPIP.setMaximumSize(new java.awt.Dimension(210, 23));
        softAPIP.setMinimumSize(new java.awt.Dimension(210, 23));
        softAPIP.setPreferredSize(new java.awt.Dimension(210, 23));

        cmdSetCIPAP.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        cmdSetCIPAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/set.png"))); // NOI18N
        cmdSetCIPAP.setText("CIPAP= 设置热点IP");
        cmdSetCIPAP.setToolTipText("设置热点IP地址");
        cmdSetCIPAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCIPAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPAPActionPerformed(evt);
            }
        });

        WiFisoftAPPane.setLayer(cmdSetCWSAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdGetCWSAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdGetCIPAPMAC, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdGetCWLIF, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(SSIDsoftAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(PASSsoftAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdGetCIPAP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdSetCIPAPMAC, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(MAC1, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(encryption, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(channel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(softAPIP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        WiFisoftAPPane.setLayer(cmdSetCIPAP, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout WiFisoftAPPaneLayout = new javax.swing.GroupLayout(WiFisoftAPPane);
        WiFisoftAPPane.setLayout(WiFisoftAPPaneLayout);
        WiFisoftAPPaneLayout.setHorizontalGroup(
            WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                        .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(MAC1, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdSetCIPAPMAC, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdGetCIPAP, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdSetCIPAP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                        .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                                .addComponent(cmdGetCIPAPMAC, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(cmdSetCWSAP, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                            .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                                    .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(cmdGetCWSAP, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(cmdGetCWLIF, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(SSIDsoftAP, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(channel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(PASSsoftAP, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(encryption, 0, 1, Short.MAX_VALUE)))
                                .addComponent(softAPIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );
        WiFisoftAPPaneLayout.setVerticalGroup(
            WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(SSIDsoftAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(PASSsoftAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdGetCWSAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                        .addGap(4, 4, 4)
                        .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(channel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(encryption, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(WiFisoftAPPaneLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdGetCWLIF, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(WiFisoftAPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdGetCIPAPMAC, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdSetCWSAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MAC1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetCIPAPMAC, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdGetCIPAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(softAPIP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetCIPAP, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(246, Short.MAX_VALUE))
        );

        TopWiFiAPFiller.setOpaque(true);

        AT_SoftAP.setLayer(WiFisoftAPPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        AT_SoftAP.setLayer(TopWiFiAPFiller, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout AT_SoftAPLayout = new javax.swing.GroupLayout(AT_SoftAP);
        AT_SoftAP.setLayout(AT_SoftAPLayout);
        AT_SoftAPLayout.setHorizontalGroup(
            AT_SoftAPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(WiFisoftAPPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(TopWiFiAPFiller, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
        );
        AT_SoftAPLayout.setVerticalGroup(
            AT_SoftAPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, AT_SoftAPLayout.createSequentialGroup()
                .addComponent(TopWiFiAPFiller, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(WiFisoftAPPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        TabAT.addTab("WiFi热点", AT_SoftAP);

        AT_Client.setToolTipText("TCP/IP相关命令");
        AT_Client.setAlignmentX(0.0F);
        AT_Client.setAlignmentY(0.0F);
        AT_Client.setOpaque(false);
        AT_Client.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                AT_ClientFocusGained(evt);
            }
        });
        AT_Client.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                AT_ClientComponentShown(evt);
            }
        });

        TopWiFiStaFiller1.setOpaque(true);

        common.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "命令的常用参数", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        common.setMaximumSize(new java.awt.Dimension(445, 54));
        common.setMinimumSize(new java.awt.Dimension(445, 54));
        common.setPreferredSize(new java.awt.Dimension(445, 54));

        conn_id.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0", "1", "2", "3", "4" }));
        conn_id.setToolTipText("连接ID");

        MUXGroup.add(single);
        single.setText("CIPMUX=0-单连接");
        single.setToolTipText("单一的连接");
        single.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                singleItemStateChanged(evt);
            }
        });

        MUXGroup.add(multi);
        multi.setSelected(true);
        multi.setText("CIPMUX=1-多连接");
        multi.setToolTipText("多个连接");
        multi.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                multiItemStateChanged(evt);
            }
        });
        multi.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                multiActionPerformed(evt);
            }
        });

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel4.setText("连接ID");

        javax.swing.GroupLayout commonLayout = new javax.swing.GroupLayout(common);
        common.setLayout(commonLayout);
        commonLayout.setHorizontalGroup(
            commonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(commonLayout.createSequentialGroup()
                .addGap(2, 2, 2)
                .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(conn_id, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(multi)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(single, javax.swing.GroupLayout.PREFERRED_SIZE, 151, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        commonLayout.setVerticalGroup(
            commonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(commonLayout.createSequentialGroup()
                .addGroup(commonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(conn_id, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(multi)
                    .addComponent(single)
                    .addComponent(jLabel4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        cmdGetCIPSTART.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/information.png"))); // NOI18N
        cmdGetCIPSTART.setText("CIPSTART=? 连接信息");
        cmdGetCIPSTART.setToolTipText("获取param的信息");
        cmdGetCIPSTART.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPSTARTActionPerformed(evt);
            }
        });

        UDP.setBorder(javax.swing.BorderFactory.createTitledBorder("UDP配置"));
        UDP.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                UDPPropertyChange(evt);
            }
        });

        udp_local_port.setToolTipText("本地UDP端口");
        udp_local_port.setEnabled(false);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel2.setText("端口");

        udp_mode.setToolTipText("本地UDP端口");
        udp_mode.setEnabled(false);

        jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel3.setText("模式");

        UDP.setLayer(udp_local_port, javax.swing.JLayeredPane.DEFAULT_LAYER);
        UDP.setLayer(jLabel2, javax.swing.JLayeredPane.DEFAULT_LAYER);
        UDP.setLayer(udp_mode, javax.swing.JLayeredPane.DEFAULT_LAYER);
        UDP.setLayer(jLabel3, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout UDPLayout = new javax.swing.GroupLayout(UDP);
        UDP.setLayout(UDPLayout);
        UDPLayout.setHorizontalGroup(
            UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(UDPLayout.createSequentialGroup()
                .addGroup(UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(udp_local_port))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(udp_mode)
                    .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(6, 6, 6))
        );
        UDPLayout.setVerticalGroup(
            UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(UDPLayout.createSequentialGroup()
                .addGroup(UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(UDPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(udp_local_port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(udp_mode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        remote_address.setText("192.168.1.1");
        remote_address.setToolTipText("远程IP地址");

        remote_port.setText("80");
        remote_port.setToolTipText("远程端口");

        protocol.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "TCP", "UDP" }));
        protocol.setToolTipText("连接类型:TCP或UDP");
        protocol.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                protocolItemStateChanged(evt);
            }
        });

        cmdSetCIPSTART.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect3.png"))); // NOI18N
        cmdSetCIPSTART.setText("AT+CIPSTART= 配置连接");
        cmdSetCIPSTART.setToolTipText("作为一个客户端连接");
        cmdSetCIPSTART.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPSTARTActionPerformed(evt);
            }
        });

        data.setColumns(15);
        data.setRows(5);
        data.setTabSize(4);
        data.setText("GET / HTTP/1.0\nHost: 192.168.1.1\nConnection: keep-alive\nAccept: */*\n\n");
        data.setToolTipText("要发送到远程客户端的数据");
        data.setCaretPosition(1);
        jScrollData.setViewportView(data);

        cmdCIPSEND.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/level up.png"))); // NOI18N
        cmdCIPSEND.setText("AT+CIPSEND= 发送数据");
        cmdCIPSEND.setToolTipText("发送数据到客户端");
        cmdCIPSEND.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdCIPSENDActionPerformed(evt);
            }
        });

        cmdCIPSENDinteractive.setText("AT+CIPSEND 交互式的 ");
        cmdCIPSENDinteractive.setToolTipText("以交互模式发送数据到远程客户端。发送完所有数据后，键入 \"+++\"");
        cmdCIPSENDinteractive.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdCIPSENDinteractiveActionPerformed(evt);
            }
        });

        cmdSetCIPCLOSE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/disconnect3.png"))); // NOI18N
        cmdSetCIPCLOSE.setText("AT+CIPCLOSE 关闭连接");
        cmdSetCIPCLOSE.setToolTipText("关闭所有连接");
        cmdSetCIPCLOSE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPCLOSEActionPerformed(evt);
            }
        });

        TCPclientBottomPane.setLayer(common, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(cmdGetCIPSTART, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(UDP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(remote_address, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(remote_port, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(protocol, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(cmdSetCIPSTART, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(jScrollData, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(cmdCIPSEND, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(cmdCIPSENDinteractive, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPclientBottomPane.setLayer(cmdSetCIPCLOSE, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout TCPclientBottomPaneLayout = new javax.swing.GroupLayout(TCPclientBottomPane);
        TCPclientBottomPane.setLayout(TCPclientBottomPaneLayout);
        TCPclientBottomPaneLayout.setHorizontalGroup(
            TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(common, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE)
            .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                .addComponent(UDP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                        .addComponent(remote_address, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(remote_port, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(protocol, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(cmdSetCIPSTART))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                .addComponent(jScrollData)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(cmdCIPSEND, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdCIPSENDinteractive, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdSetCIPCLOSE, javax.swing.GroupLayout.PREFERRED_SIZE, 230, Short.MAX_VALUE))
                    .addComponent(cmdGetCIPSTART, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 230, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );
        TCPclientBottomPaneLayout.setVerticalGroup(
            TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, TCPclientBottomPaneLayout.createSequentialGroup()
                .addComponent(common, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                        .addGap(18, 18, 18)
                        .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(remote_address, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(remote_port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(protocol, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdSetCIPSTART))
                    .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(UDP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(TCPclientBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(TCPclientBottomPaneLayout.createSequentialGroup()
                        .addComponent(cmdGetCIPSTART)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdCIPSEND)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdCIPSENDinteractive)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdSetCIPCLOSE)
                        .addContainerGap(258, Short.MAX_VALUE))
                    .addComponent(jScrollData)))
        );

        javax.swing.GroupLayout AT_ClientLayout = new javax.swing.GroupLayout(AT_Client);
        AT_Client.setLayout(AT_ClientLayout);
        AT_ClientLayout.setHorizontalGroup(
            AT_ClientLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TCPclientBottomPane)
            .addComponent(TopWiFiStaFiller1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        AT_ClientLayout.setVerticalGroup(
            AT_ClientLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(AT_ClientLayout.createSequentialGroup()
                .addComponent(TopWiFiStaFiller1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(TCPclientBottomPane))
        );

        TabAT.addTab("TCP/IP 客户端", AT_Client);
        AT_Client.getAccessibleContext().setAccessibleName("AT_IP");
        AT_Client.getAccessibleContext().setAccessibleDescription("");

        AT_Server.setOpaque(false);
        AT_Server.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                AT_ServerFocusGained(evt);
            }
        });
        AT_Server.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                AT_ServerComponentShown(evt);
            }
        });

        TCPServerTopFiller.setOpaque(true);

        TCPServerBottomPane.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        TCPServerBottomPane.setMaximumSize(new java.awt.Dimension(463, 377));
        TCPServerBottomPane.setMinimumSize(new java.awt.Dimension(463, 377));
        TCPServerBottomPane.setOpaque(true);

        cmdGetCIPMODE.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        cmdGetCIPMODE.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/information.png"))); // NOI18N
        cmdGetCIPMODE.setText("CIPMODE? 0 - 正常");
        cmdGetCIPMODE.setToolTipText("获取数据传输模式(0-正常，1 -直接)");
        cmdGetCIPMODE.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPMODE.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdGetCIPMODE.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdGetCIPMODE.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdGetCIPMODE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPMODEActionPerformed(evt);
            }
        });

        cmdSetCIPMODE0.setText("CIPMODE=0");
        cmdSetCIPMODE0.setToolTipText("设置数据传输模式为0(正常模式)");
        cmdSetCIPMODE0.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPMODE0.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE0.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE0.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPMODE0ActionPerformed(evt);
            }
        });

        cmdSetCIPMODE1.setText("CIPMODE=1");
        cmdSetCIPMODE1.setToolTipText("设置数据传输模式为1(直接模式)");
        cmdSetCIPMODE1.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPMODE1.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE1.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE1.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdSetCIPMODE1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPMODE1ActionPerformed(evt);
            }
        });

        cmdSetCIPSERVER.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/web_server_start.png"))); // NOI18N
        cmdSetCIPSERVER.setText("CIPSERVER 启动/关闭");
        cmdSetCIPSERVER.setToolTipText("设置TCP服务器(启动和关闭)");
        cmdSetCIPSERVER.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPSERVER.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSERVER.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSERVER.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSERVER.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPSERVERActionPerformed(evt);
            }
        });

        ServerMode.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0 - 删除服务器", "1 - 创建服务器" }));
        ServerMode.setSelectedIndex(1);
        ServerMode.setToolTipText("用CIPSERVER命令选择模式");
        ServerMode.setAlignmentX(0.0F);
        ServerMode.setMaximumSize(new java.awt.Dimension(120, 23));
        ServerMode.setMinimumSize(new java.awt.Dimension(120, 23));
        ServerMode.setPreferredSize(new java.awt.Dimension(120, 23));
        ServerMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ServerModeActionPerformed(evt);
            }
        });

        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel5.setText("端口");

        ServerPort.setText("80");
        ServerPort.setMaximumSize(new java.awt.Dimension(100, 23));
        ServerPort.setMinimumSize(new java.awt.Dimension(100, 23));
        ServerPort.setPreferredSize(new java.awt.Dimension(100, 23));

        cmdGetCIPSTO.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/get.png"))); // NOI18N
        cmdGetCIPSTO.setText("CIPSTO? 获取超时时间");
        cmdGetCIPSTO.setToolTipText("获取当前服务器超时时间");
        cmdGetCIPSTO.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCIPSTO.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdGetCIPSTO.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdGetCIPSTO.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdGetCIPSTO.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPSTOActionPerformed(evt);
            }
        });

        cmdSetCIPSTO.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/set.png"))); // NOI18N
        cmdSetCIPSTO.setText("CIPSTO= 设置超时时间");
        cmdSetCIPSTO.setToolTipText("设置当前服务器超时时间");
        cmdSetCIPSTO.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCIPSTO.setMaximumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSTO.setMinimumSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSTO.setPreferredSize(new java.awt.Dimension(120, 23));
        cmdSetCIPSTO.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPSTOActionPerformed(evt);
            }
        });

        ServerTimeout.setText("60");
        ServerTimeout.setToolTipText("设置服务器超时");
        ServerTimeout.setMaximumSize(new java.awt.Dimension(120, 23));
        ServerTimeout.setMinimumSize(new java.awt.Dimension(120, 23));
        ServerTimeout.setPreferredSize(new java.awt.Dimension(120, 23));

        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel6.setText("服务器超时");

        TCPServerBottomPane.setLayer(cmdGetCIPMODE, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(cmdSetCIPMODE0, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(cmdSetCIPMODE1, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(cmdSetCIPSERVER, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(ServerMode, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(jLabel5, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(ServerPort, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(cmdGetCIPSTO, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(cmdSetCIPSTO, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(ServerTimeout, javax.swing.JLayeredPane.DEFAULT_LAYER);
        TCPServerBottomPane.setLayer(jLabel6, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout TCPServerBottomPaneLayout = new javax.swing.GroupLayout(TCPServerBottomPane);
        TCPServerBottomPane.setLayout(TCPServerBottomPaneLayout);
        TCPServerBottomPaneLayout.setHorizontalGroup(
            TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(TCPServerBottomPaneLayout.createSequentialGroup()
                .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(cmdSetCIPSERVER, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(ServerMode, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdSetCIPSTO, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(TCPServerBottomPaneLayout.createSequentialGroup()
                                    .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(ServerTimeout, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(cmdSetCIPMODE1, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(cmdGetCIPSTO, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addComponent(cmdGetCIPMODE, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(cmdSetCIPMODE0, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(TCPServerBottomPaneLayout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(ServerPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        TCPServerBottomPaneLayout.setVerticalGroup(
            TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(TCPServerBottomPaneLayout.createSequentialGroup()
                .addComponent(cmdGetCIPMODE, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(cmdSetCIPMODE0, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(cmdSetCIPMODE1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(cmdGetCIPSTO, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(ServerTimeout, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(cmdSetCIPSTO, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ServerMode, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(TCPServerBottomPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(ServerPort, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSetCIPSERVER, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 304, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout AT_ServerLayout = new javax.swing.GroupLayout(AT_Server);
        AT_Server.setLayout(AT_ServerLayout);
        AT_ServerLayout.setHorizontalGroup(
            AT_ServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(TCPServerBottomPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(TCPServerTopFiller, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
        );
        AT_ServerLayout.setVerticalGroup(
            AT_ServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, AT_ServerLayout.createSequentialGroup()
                .addComponent(TCPServerTopFiller, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(TCPServerBottomPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        TabAT.addTab("TCP/IP服务器", AT_Server);

        ATvXX.add(TabAT, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 70, 440, 645));

        TCP_common.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "常见的TCP命令"));
        TCP_common.setAlignmentX(0.0F);
        TCP_common.setAlignmentY(0.0F);
        TCP_common.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        TCP_common.setMaximumSize(new java.awt.Dimension(445, 45));
        TCP_common.setMinimumSize(new java.awt.Dimension(445, 45));
        TCP_common.setOpaque(true);
        TCP_common.setLayout(new java.awt.FlowLayout());

        cmdGetCIPSTATUS.setText("CIPSTATUS");
        cmdGetCIPSTATUS.setToolTipText("获取关于连接的信息(2获得IP, 3连接，4断开连接)");
        cmdGetCIPSTATUS.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPSTATUSActionPerformed(evt);
            }
        });
        TCP_common.add(cmdGetCIPSTATUS);

        cmdGetCIPMUX.setText("CIPMUX?");
        cmdGetCIPMUX.setToolTipText("获取有关当前模式的信息:允许单连接或多连接");
        cmdGetCIPMUX.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIPMUXActionPerformed(evt);
            }
        });
        TCP_common.add(cmdGetCIPMUX);

        cmdSetCIPMUX1.setText("CIPMUX=1");
        cmdSetCIPMUX1.setToolTipText("设置模式为允许多个连接");
        cmdSetCIPMUX1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPMUX1ActionPerformed(evt);
            }
        });
        TCP_common.add(cmdSetCIPMUX1);

        cmdSetCIPMUX0.setText("CIPMUX=0");
        cmdSetCIPMUX0.setToolTipText("设置模式，只允许一个连接");
        cmdSetCIPMUX0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCIPMUX0ActionPerformed(evt);
            }
        });
        TCP_common.add(cmdSetCIPMUX0);

        cmdGetCIFSR.setText("CIFSR");
        cmdGetCIFSR.setToolTipText("获取本地IP地址(热点或连接)");
        cmdGetCIFSR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCIFSRActionPerformed(evt);
            }
        });
        TCP_common.add(cmdGetCIFSR);

        ATvXX.setLayer(TCP_common, javax.swing.JLayeredPane.PALETTE_LAYER);
        ATvXX.add(TCP_common, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 100, 540, 60));

        WiFi_common.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "常见的无线网络命令"));
        WiFi_common.setAlignmentX(0.0F);
        WiFi_common.setAlignmentY(0.0F);
        WiFi_common.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        WiFi_common.setName(""); // NOI18N
        WiFi_common.setOpaque(true);
        WiFi_common.setPreferredSize(new java.awt.Dimension(445, 110));
        WiFi_common.setLayout(new java.awt.FlowLayout());

        cmdGetHelpCWMODE.setText("CWMODE=? 获得可用的模式");
        cmdGetHelpCWMODE.setToolTipText("获取WiFi模式的值范围(常见WIFI模式)");
        cmdGetHelpCWMODE.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetHelpCWMODE.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetHelpCWMODE.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetHelpCWMODE.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetHelpCWMODE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetHelpCWMODEActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdGetHelpCWMODE);

        cmdSetCWMODE1.setText("CWMODE=1 WIFI模式");
        cmdSetCWMODE1.setToolTipText("设置ESP8266 WiFi模式1 - Station");
        cmdSetCWMODE1.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWMODE1.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE1.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE1.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWMODE1ActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdSetCWMODE1);

        cmdGetCWMODE.setText("CWMODE? 获取当前模式");
        cmdGetCWMODE.setToolTipText("查询ESP8266当前的WiFi模式。(CommandWifiMODE)");
        cmdGetCWMODE.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdGetCWMODE.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdGetCWMODE.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdGetCWMODE.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdGetCWMODE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdGetCWMODEActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdGetCWMODE);

        cmdSetCWMODE2.setText("CWMODE=2 热点模式");
        cmdSetCWMODE2.setToolTipText("设置ESP8266 WiFi模式2 -热点模式");
        cmdSetCWMODE2.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWMODE2.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE2.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE2.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWMODE2ActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdSetCWMODE2);

        cmdSetCWLAP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/search again.png"))); // NOI18N
        cmdSetCWLAP.setText("CWLAP 获取热点列表");
        cmdSetCWLAP.setToolTipText("列出所有可用的WiFi接入点");
        cmdSetCWLAP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWLAP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWLAP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWLAP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWLAP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWLAPActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdSetCWLAP);

        cmdSetCWMODE3.setText("CWMODE=3 热点和WIFI模式");
        cmdSetCWMODE3.setToolTipText("设置ESP8266 WiFi模式3 -热点模式+基站模式");
        cmdSetCWMODE3.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWMODE3.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE3.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE3.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWMODE3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWMODE3ActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdSetCWMODE3);

        DHCP.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0 - 开启 DHCP", "1 - 关闭 DHCP" }));
        DHCP.setMaximumSize(new java.awt.Dimension(114, 23));
        DHCP.setMinimumSize(new java.awt.Dimension(114, 23));
        DHCP.setPreferredSize(new java.awt.Dimension(114, 23));
        WiFi_common.add(DHCP);

        DHCPmode.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0 - 设置热点", "1 - 设置WIFI", "2 - 设置热点和WIFI" }));
        DHCPmode.setSelectedIndex(1);
        DHCPmode.setMaximumSize(new java.awt.Dimension(90, 23));
        DHCPmode.setMinimumSize(new java.awt.Dimension(90, 23));
        DHCPmode.setPreferredSize(new java.awt.Dimension(90, 23));
        WiFi_common.add(DHCPmode);

        cmdSetCWDHCP.setText("AT+CWDHCP DHCP控制");
        cmdSetCWDHCP.setToolTipText("启用/禁用 DHCP");
        cmdSetCWDHCP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSetCWDHCP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdSetCWDHCP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSetCWDHCP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdSetCWDHCP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSetCWDHCPActionPerformed(evt);
            }
        });
        WiFi_common.add(cmdSetCWDHCP);

        ATvXX.setLayer(WiFi_common, javax.swing.JLayeredPane.PALETTE_LAYER);
        ATvXX.add(WiFi_common, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 100, 540, 140));

        LeftTab.addTab(" AT-指令 ", ATvXX);

        RN2483.setOpaque(true);

        MacPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        LoRaMAC.setOpaque(true);
        LoRaMAC.setPreferredSize(new java.awt.Dimension(729, 600));

        MacCommon.setBorder(javax.swing.BorderFactory.createTitledBorder("参数"));

        cmdMacSetAdrOn.setText("mac 设置adr开启");
        cmdMacSetAdrOn.setToolTipText("重启系统");
        cmdMacSetAdrOn.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetAdrOn.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOn.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOn.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetAdrOnActionPerformed(evt);
            }
        });

        cmdMacSetDR.setText("mac 设置数据速率(dr)");
        cmdMacSetDR.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetDR.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDR.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDR.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetDR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetDRActionPerformed(evt);
            }
        });

        cmdMacSetPwrIdx.setText("mac 设置 pwridx (电源)");
        cmdMacSetPwrIdx.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetPwrIdx.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetPwrIdx.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetPwrIdx.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetPwrIdx.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetPwrIdxActionPerformed(evt);
            }
        });

        cmdMacGetStatus.setText("mac 获取状态");
        cmdMacGetStatus.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetStatus.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetStatus.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetStatus.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetStatus.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetStatusActionPerformed(evt);
            }
        });

        cmdMacSetAdrOff.setText("mac 设置adr关闭");
        cmdMacSetAdrOff.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetAdrOff.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOff.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOff.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetAdrOff.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetAdrOffActionPerformed(evt);
            }
        });

        cmdMacGetAdr.setText("mac 获取adr");
        cmdMacGetAdr.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetAdr.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetAdr.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetAdr.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetAdr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetAdrActionPerformed(evt);
            }
        });

        MacDR.setText("5");
        MacDR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MacDRActionPerformed(evt);
            }
        });

        MacPower.setText("1");
        MacPower.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MacPowerActionPerformed(evt);
            }
        });

        cmdMacGetDR.setText("mac 获取信息速率(dr)");
        cmdMacGetDR.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetDR.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDR.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDR.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetDR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetDRActionPerformed(evt);
            }
        });

        cmdMacGetPwrIdx.setText("mac 获取pwridx");
        cmdMacGetPwrIdx.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetPwrIdx.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetPwrIdx.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetPwrIdx.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetPwrIdx.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetPwrIdxActionPerformed(evt);
            }
        });

        MacCommon.setLayer(cmdMacSetAdrOn, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacSetDR, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacSetPwrIdx, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacGetStatus, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacSetAdrOff, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacGetAdr, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(MacDR, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(MacPower, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacGetDR, javax.swing.JLayeredPane.DEFAULT_LAYER);
        MacCommon.setLayer(cmdMacGetPwrIdx, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout MacCommonLayout = new javax.swing.GroupLayout(MacCommon);
        MacCommon.setLayout(MacCommonLayout);
        MacCommonLayout.setHorizontalGroup(
            MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(MacCommonLayout.createSequentialGroup()
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(cmdMacGetStatus, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 180, Short.MAX_VALUE)
                    .addComponent(cmdMacSetPwrIdx, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacSetDR, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacSetAdrOn, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmdMacSetAdrOff, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MacDR)
                    .addComponent(MacPower))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(cmdMacGetDR, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(cmdMacGetAdr, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                    .addComponent(cmdMacGetPwrIdx, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        MacCommonLayout.setVerticalGroup(
            MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(MacCommonLayout.createSequentialGroup()
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetAdrOn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacSetAdrOff, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetAdr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetDR, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MacDR, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetDR, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(MacCommonLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetPwrIdx, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MacPower, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetPwrIdx, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMacGetStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        SendUnconfirmed.setBorder(javax.swing.BorderFactory.createTitledBorder("发送数据"));

        cmdMacTX.setText("传输数据");
        cmdMacTX.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacTX.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacTX.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacTX.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacTX.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacTXActionPerformed(evt);
            }
        });

        MacTxPort.setText("16");

        MacTxData.setText("48454c4c4f");

        TxConfirmed.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "uncnf", "cnf", " " }));
        TxConfirmed.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                TxConfirmedItemStateChanged(evt);
            }
        });
        TxConfirmed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                TxConfirmedActionPerformed(evt);
            }
        });

        jLabel13.setText("默认: HELLO");

        SendUnconfirmed.setLayer(cmdMacTX, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SendUnconfirmed.setLayer(MacTxPort, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SendUnconfirmed.setLayer(MacTxData, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SendUnconfirmed.setLayer(TxConfirmed, javax.swing.JLayeredPane.DEFAULT_LAYER);
        SendUnconfirmed.setLayer(jLabel13, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout SendUnconfirmedLayout = new javax.swing.GroupLayout(SendUnconfirmed);
        SendUnconfirmed.setLayout(SendUnconfirmedLayout);
        SendUnconfirmedLayout.setHorizontalGroup(
            SendUnconfirmedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SendUnconfirmedLayout.createSequentialGroup()
                .addComponent(cmdMacTX, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(TxConfirmed, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MacTxPort, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(SendUnconfirmedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel13, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(MacTxData))
                .addContainerGap())
        );
        SendUnconfirmedLayout.setVerticalGroup(
            SendUnconfirmedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(SendUnconfirmedLayout.createSequentialGroup()
                .addComponent(jLabel13)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(SendUnconfirmedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(MacTxData, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MacTxPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addGroup(SendUnconfirmedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(cmdMacTX, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(TxConfirmed, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        RadioPane.setBorder(javax.swing.BorderFactory.createTitledBorder("广播"));

        MacSF.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "sf7", "sf8", "sf9", "sf10", "sf11", "sf12", " " }));
        MacSF.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MacSFItemStateChanged(evt);
            }
        });
        MacSF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MacSFActionPerformed(evt);
            }
        });

        jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel11.setText("分布系数");

        RadioRxBandWidth.setText("25");

        RadioFreq.setText("868100000");

        cmdRadiosetRxBw.setText("设置rx波段宽度");
        cmdRadiosetRxBw.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadiosetRxBw.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadiosetRxBw.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadiosetRxBw.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadiosetRxBw.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadiosetRxBwActionPerformed(evt);
            }
        });

        cmdRadioSetFreq.setText("设置广播频率");
        cmdRadioSetFreq.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadioSetFreq.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadioSetFreq.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadioSetFreq.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadioSetFreq.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadioSetFreqActionPerformed(evt);
            }
        });

        cmdRadioGetSF.setText("获取");
        cmdRadioGetSF.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadioGetSF.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetSF.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetSF.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadioGetSF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadioGetSFActionPerformed(evt);
            }
        });

        cmdRadioGetBw.setText("获取");
        cmdRadioGetBw.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadioGetBw.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetBw.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetBw.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadioGetBw.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadioGetBwActionPerformed(evt);
            }
        });

        cmdRadioGetRxBw.setText("获取");
        cmdRadioGetRxBw.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadioGetRxBw.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetRxBw.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetRxBw.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadioGetRxBw.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadioGetRxBwActionPerformed(evt);
            }
        });

        cmdRadioGetFreq.setText("获取");
        cmdRadioGetFreq.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdRadioGetFreq.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetFreq.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdRadioGetFreq.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdRadioGetFreq.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRadioGetFreqActionPerformed(evt);
            }
        });

        MacBandWidth.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "125", "250", "500", " " }));
        MacBandWidth.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MacBandWidthItemStateChanged(evt);
            }
        });
        MacBandWidth.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MacBandWidthActionPerformed(evt);
            }
        });

        jLabel12.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel12.setText("Band Width");

        RadioPane.setLayer(MacSF, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(jLabel11, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(RadioRxBandWidth, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(RadioFreq, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadiosetRxBw, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadioSetFreq, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadioGetSF, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadioGetBw, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadioGetRxBw, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(cmdRadioGetFreq, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(MacBandWidth, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RadioPane.setLayer(jLabel12, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout RadioPaneLayout = new javax.swing.GroupLayout(RadioPane);
        RadioPane.setLayout(RadioPaneLayout);
        RadioPaneLayout.setHorizontalGroup(
            RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(RadioPaneLayout.createSequentialGroup()
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdRadiosetRxBw, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(cmdRadioSetFreq, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel12, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(MacSF, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(RadioRxBandWidth)
                    .addComponent(RadioFreq, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
                    .addComponent(MacBandWidth, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(cmdRadioGetSF, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addComponent(cmdRadioGetBw, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdRadioGetRxBw, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdRadioGetFreq, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                .addGap(92, 92, 92))
        );
        RadioPaneLayout.setVerticalGroup(
            RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(RadioPaneLayout.createSequentialGroup()
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel11)
                        .addComponent(MacSF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(cmdRadioGetSF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdRadioGetBw, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MacBandWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel12))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdRadiosetRxBw, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(RadioRxBandWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdRadioGetRxBw, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(RadioPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdRadioSetFreq, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(RadioFreq, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdRadioGetFreq, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jLayeredPane1.setBorder(javax.swing.BorderFactory.createTitledBorder("系统"));

        cmdSysReset.setText("重启系统");
        cmdSysReset.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSysReset.setMaximumSize(new java.awt.Dimension(210, 30));
        cmdSysReset.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSysReset.setPreferredSize(new java.awt.Dimension(210, 40));
        cmdSysReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSysResetActionPerformed(evt);
            }
        });

        cmdSysFactoryReset.setText("重置系统");
        cmdSysFactoryReset.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSysFactoryReset.setMaximumSize(new java.awt.Dimension(210, 30));
        cmdSysFactoryReset.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSysFactoryReset.setPreferredSize(new java.awt.Dimension(210, 40));
        cmdSysFactoryReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSysFactoryResetActionPerformed(evt);
            }
        });

        cmdSysGetVer.setText("系统版本");
        cmdSysGetVer.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSysGetVer.setMaximumSize(new java.awt.Dimension(210, 30));
        cmdSysGetVer.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSysGetVer.setPreferredSize(new java.awt.Dimension(210, 40));
        cmdSysGetVer.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSysGetVerActionPerformed(evt);
            }
        });

        cmdSysGetHwEui.setText("系统地址");
        cmdSysGetHwEui.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdSysGetHwEui.setMaximumSize(new java.awt.Dimension(210, 30));
        cmdSysGetHwEui.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdSysGetHwEui.setPreferredSize(new java.awt.Dimension(210, 40));
        cmdSysGetHwEui.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSysGetHwEuiActionPerformed(evt);
            }
        });

        jLayeredPane1.setLayer(cmdSysReset, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane1.setLayer(cmdSysFactoryReset, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane1.setLayer(cmdSysGetVer, javax.swing.JLayeredPane.DEFAULT_LAYER);
        jLayeredPane1.setLayer(cmdSysGetHwEui, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout jLayeredPane1Layout = new javax.swing.GroupLayout(jLayeredPane1);
        jLayeredPane1.setLayout(jLayeredPane1Layout);
        jLayeredPane1Layout.setHorizontalGroup(
            jLayeredPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jLayeredPane1Layout.createSequentialGroup()
                .addComponent(cmdSysReset, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSysFactoryReset, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSysGetVer, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdSysGetHwEui, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(20, Short.MAX_VALUE))
        );
        jLayeredPane1Layout.setVerticalGroup(
            jLayeredPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jLayeredPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(cmdSysReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(cmdSysGetVer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(cmdSysFactoryReset, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(cmdSysGetHwEui, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        LoRaMAC.setLayer(MacCommon, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LoRaMAC.setLayer(SendUnconfirmed, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LoRaMAC.setLayer(RadioPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LoRaMAC.setLayer(jLayeredPane1, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout LoRaMACLayout = new javax.swing.GroupLayout(LoRaMAC);
        LoRaMAC.setLayout(LoRaMACLayout);
        LoRaMACLayout.setHorizontalGroup(
            LoRaMACLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(LoRaMACLayout.createSequentialGroup()
                .addGroup(LoRaMACLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(MacCommon)
                    .addComponent(RadioPane)
                    .addComponent(SendUnconfirmed)
                    .addComponent(jLayeredPane1))
                .addGap(199, 199, 199))
        );
        LoRaMACLayout.setVerticalGroup(
            LoRaMACLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(LoRaMACLayout.createSequentialGroup()
                .addComponent(MacCommon, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(RadioPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(SendUnconfirmed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 204, Short.MAX_VALUE))
        );

        MacPane.setViewportView(LoRaMAC);

        RN2483jTab.addTab("MAC和广播", MacPane);

        ActivationPane.setPreferredSize(new java.awt.Dimension(537, 600));

        ABPPane.setBorder(javax.swing.BorderFactory.createTitledBorder("激活的个性化"));

        cmdMacSetDevAddr.setText("设置设备地址");
        cmdMacSetDevAddr.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetDevAddr.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevAddr.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevAddr.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevAddr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetDevAddrActionPerformed(evt);
            }
        });

        cmdMacSetNwkSKey.setText("设置网络秘钥");
        cmdMacSetNwkSKey.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetNwkSKey.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetNwkSKey.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetNwkSKey.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetNwkSKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetNwkSKeyActionPerformed(evt);
            }
        });

        cmdMacSetAppSKey.setText("设置应用秘钥");
        cmdMacSetAppSKey.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetAppSKey.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppSKey.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppSKey.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppSKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetAppSKeyActionPerformed(evt);
            }
        });

        cmdMacjoinABP.setText("加入ABP");
        cmdMacjoinABP.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacjoinABP.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacjoinABP.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacjoinABP.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacjoinABP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacjoinABPActionPerformed(evt);
            }
        });

        cmdMacGetDevAddr.setText("获取");
        cmdMacGetDevAddr.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetDevAddr.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevAddr.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevAddr.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevAddr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetDevAddrActionPerformed(evt);
            }
        });

        DevAddr.setText("00000000");
        DevAddr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DevAddrActionPerformed(evt);
            }
        });

        NwkSKey.setText("2B7E151628AED2A6ABF7158809CF4F3C");
        NwkSKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NwkSKeyActionPerformed(evt);
            }
        });

        AppSKey.setText("2B7E151628AED2A6ABF7158809CF4F3C");
        AppSKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AppSKeyActionPerformed(evt);
            }
        });

        ABPPane.setLayer(cmdMacSetDevAddr, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(cmdMacSetNwkSKey, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(cmdMacSetAppSKey, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(cmdMacjoinABP, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(cmdMacGetDevAddr, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(DevAddr, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(NwkSKey, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ABPPane.setLayer(AppSKey, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout ABPPaneLayout = new javax.swing.GroupLayout(ABPPane);
        ABPPane.setLayout(ABPPaneLayout);
        ABPPaneLayout.setHorizontalGroup(
            ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ABPPaneLayout.createSequentialGroup()
                .addGroup(ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(cmdMacSetAppSKey, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacSetNwkSKey, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacSetDevAddr, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacjoinABP, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(NwkSKey)
                    .addComponent(DevAddr)
                    .addComponent(AppSKey))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMacGetDevAddr, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
        );
        ABPPaneLayout.setVerticalGroup(
            ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ABPPaneLayout.createSequentialGroup()
                .addGroup(ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetDevAddr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(DevAddr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetDevAddr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetNwkSKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(NwkSKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ABPPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetAppSKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AppSKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(cmdMacjoinABP, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        cmdMacSave.setText("保存");
        cmdMacSave.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSave.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSave.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSave.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSaveActionPerformed(evt);
            }
        });

        OTAAPane.setBorder(javax.swing.BorderFactory.createTitledBorder("空中激活"));

        cmdMacSetDevEui.setText("设置设备");
        cmdMacSetDevEui.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetDevEui.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevEui.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevEui.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetDevEui.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetDevEuiActionPerformed(evt);
            }
        });

        cmdMacSetAppEui.setText("设置应用");
        cmdMacSetAppEui.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetAppEui.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppEui.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppEui.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppEui.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetAppEuiActionPerformed(evt);
            }
        });

        cmdMacSetAppKey.setText("设置秘钥");
        cmdMacSetAppKey.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacSetAppKey.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppKey.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppKey.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacSetAppKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacSetAppKeyActionPerformed(evt);
            }
        });

        cmdMacJoinOTAA.setText("加入OTAA");
        cmdMacJoinOTAA.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacJoinOTAA.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacJoinOTAA.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacJoinOTAA.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacJoinOTAA.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacJoinOTAAActionPerformed(evt);
            }
        });

        cmdMacGetDevEui.setText("获取");
        cmdMacGetDevEui.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetDevEui.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevEui.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevEui.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetDevEui.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetDevEuiActionPerformed(evt);
            }
        });

        cmdMacGetAppEui.setText("获取");
        cmdMacGetAppEui.setMargin(new java.awt.Insets(2, 2, 2, 2));
        cmdMacGetAppEui.setMaximumSize(new java.awt.Dimension(210, 23));
        cmdMacGetAppEui.setMinimumSize(new java.awt.Dimension(210, 23));
        cmdMacGetAppEui.setPreferredSize(new java.awt.Dimension(210, 23));
        cmdMacGetAppEui.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdMacGetAppEuiActionPerformed(evt);
            }
        });

        DevEUI.setText("输入设备 EUI");
        DevEUI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DevEUIActionPerformed(evt);
            }
        });

        AppEUI.setText("输入APP EUI");
        AppEUI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AppEUIActionPerformed(evt);
            }
        });

        AppKey.setText("输入App秘钥");
        AppKey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AppKeyActionPerformed(evt);
            }
        });

        OTAAPane.setLayer(cmdMacSetDevEui, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(cmdMacSetAppEui, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(cmdMacSetAppKey, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(cmdMacJoinOTAA, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(cmdMacGetDevEui, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(cmdMacGetAppEui, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(DevEUI, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(AppEUI, javax.swing.JLayeredPane.DEFAULT_LAYER);
        OTAAPane.setLayer(AppKey, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout OTAAPaneLayout = new javax.swing.GroupLayout(OTAAPane);
        OTAAPane.setLayout(OTAAPaneLayout);
        OTAAPaneLayout.setHorizontalGroup(
            OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(OTAAPaneLayout.createSequentialGroup()
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmdMacSetDevEui, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacSetAppEui, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacSetAppKey, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(cmdMacJoinOTAA, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(AppEUI)
                    .addComponent(DevEUI, javax.swing.GroupLayout.DEFAULT_SIZE, 204, Short.MAX_VALUE)
                    .addComponent(AppKey))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmdMacGetDevEui, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetAppEui, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        OTAAPaneLayout.setVerticalGroup(
            OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, OTAAPaneLayout.createSequentialGroup()
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetDevEui, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(DevEUI, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetDevEui, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetAppEui, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AppEUI, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmdMacGetAppEui, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(OTAAPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdMacSetAppKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AppKey, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cmdMacJoinOTAA, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        ActivationPane.setLayer(ABPPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ActivationPane.setLayer(cmdMacSave, javax.swing.JLayeredPane.DEFAULT_LAYER);
        ActivationPane.setLayer(OTAAPane, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout ActivationPaneLayout = new javax.swing.GroupLayout(ActivationPane);
        ActivationPane.setLayout(ActivationPaneLayout);
        ActivationPaneLayout.setHorizontalGroup(
            ActivationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ActivationPaneLayout.createSequentialGroup()
                .addGroup(ActivationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(OTAAPane, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(ABPPane, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(cmdMacSave, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(19, 19, 19))
        );
        ActivationPaneLayout.setVerticalGroup(
            ActivationPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ActivationPaneLayout.createSequentialGroup()
                .addComponent(ABPPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(1, 1, 1)
                .addComponent(cmdMacSave, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(OTAAPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 298, Short.MAX_VALUE))
        );

        ActivationScrollPane.setViewportView(ActivationPane);

        RN2483jTab.addTab(" 激活 ", ActivationScrollPane);

        RN2483.setLayer(RN2483jTab, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout RN2483Layout = new javax.swing.GroupLayout(RN2483);
        RN2483.setLayout(RN2483Layout);
        RN2483Layout.setHorizontalGroup(
            RN2483Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(RN2483jTab, javax.swing.GroupLayout.DEFAULT_SIZE, 504, Short.MAX_VALUE)
        );
        RN2483Layout.setVerticalGroup(
            RN2483Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(RN2483jTab, javax.swing.GroupLayout.DEFAULT_SIZE, 696, Short.MAX_VALUE)
        );

        LeftTab.addTab(" RN2483 ", RN2483);

        LeftBasePane.setLayer(LeftTab, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout LeftBasePaneLayout = new javax.swing.GroupLayout(LeftBasePane);
        LeftBasePane.setLayout(LeftBasePaneLayout);
        LeftBasePaneLayout.setHorizontalGroup(
            LeftBasePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(LeftTab, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE)
        );
        LeftBasePaneLayout.setVerticalGroup(
            LeftBasePaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(LeftTab, javax.swing.GroupLayout.DEFAULT_SIZE, 742, Short.MAX_VALUE)
        );

        LeftTab.getAccessibleContext().setAccessibleName("左面板");

        HorizontSplit.setLeftComponent(LeftBasePane);

        RightBasePane.setOpaque(true);
        RightBasePane.setLayout(new javax.swing.BoxLayout(RightBasePane, javax.swing.BoxLayout.PAGE_AXIS));

        LEDPanel.setOpaque(true);

        PortOpenLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        PortOpenLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        PortOpenLabel.setText("打开");
        PortOpenLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        PortOpenLabel.setMaximumSize(new java.awt.Dimension(50, 25));
        PortOpenLabel.setMinimumSize(new java.awt.Dimension(50, 25));
        PortOpenLabel.setPreferredSize(new java.awt.Dimension(50, 25));
        PortOpenLabel.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

        PortCTS.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        PortCTS.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        PortCTS.setText("CTS");
        PortCTS.setToolTipText("Clear To Send 清除发送");
        PortCTS.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        PortCTS.setMaximumSize(new java.awt.Dimension(50, 25));
        PortCTS.setMinimumSize(new java.awt.Dimension(50, 25));
        PortCTS.setPreferredSize(new java.awt.Dimension(50, 25));
        PortCTS.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

        PortDTR.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        PortDTR.setText("DTR");
        PortDTR.setToolTipText("Data Terminal Ready 终端数据准备好");
        PortDTR.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        PortDTR.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        PortDTR.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        PortDTR.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PortDTRActionPerformed(evt);
            }
        });

        PortRTS.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"))); // NOI18N
        PortRTS.setText("RTS");
        PortRTS.setToolTipText("Request To Send 请求发送");
        PortRTS.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        PortRTS.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        PortRTS.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        PortRTS.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PortRTSActionPerformed(evt);
            }
        });

        Open.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect1.png"))); // NOI18N
        Open.setText("打开");
        Open.setToolTipText("打开/关闭选定的串口");
        Open.setIconTextGap(2);
        Open.setMargin(new java.awt.Insets(1, 1, 1, 1));
        Open.setMaximumSize(new java.awt.Dimension(100, 25));
        Open.setMinimumSize(new java.awt.Dimension(85, 25));
        Open.setPreferredSize(new java.awt.Dimension(80, 25));
        Open.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OpenActionPerformed(evt);
            }
        });

        Speed.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1200", "2400", "4800", "9600", "19200", "38400", "57600", "74880", "115200", "230400", "460800", "921600" }));
        Speed.setToolTipText("选择波特率");
        Speed.setMaximumSize(new java.awt.Dimension(80, 25));
        Speed.setMinimumSize(new java.awt.Dimension(80, 25));
        Speed.setPreferredSize(new java.awt.Dimension(80, 25));
        Speed.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SpeedItemStateChanged(evt);
            }
        });
        Speed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SpeedActionPerformed(evt);
            }
        });
        Speed.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                SpeedFocusLost(evt);
            }
        });

        ReScan.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/refresh3.png"))); // NOI18N
        ReScan.setToolTipText("扫描系统可用的串口");
        ReScan.setMaximumSize(new java.awt.Dimension(25, 25));
        ReScan.setMinimumSize(new java.awt.Dimension(25, 25));
        ReScan.setPreferredSize(new java.awt.Dimension(25, 25));
        ReScan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ReScanActionPerformed(evt);
            }
        });

        AutoScroll.setSelected(true);
        AutoScroll.setText("自动滚动");
        AutoScroll.setToolTipText("启用/禁用终端的自动滚动");
        AutoScroll.setMinimumSize(new java.awt.Dimension(70, 25));
        AutoScroll.setPreferredSize(new java.awt.Dimension(60, 25));
        AutoScroll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AutoScrollActionPerformed(evt);
            }
        });

        Port.setMaximumRowCount(20);
        Port.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "COM1", "COM3" }));
        Port.setToolTipText("串口选择");
        Port.setMaximumSize(new java.awt.Dimension(150, 25));
        Port.setMinimumSize(new java.awt.Dimension(150, 25));
        Port.setPreferredSize(new java.awt.Dimension(150, 25));
        Port.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                PortItemStateChanged(evt);
            }
        });
        Port.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PortActionPerformed(evt);
            }
        });

        EOL.setText("启用行尾");
        EOL.setToolTipText("启用/禁用 EOL");
        EOL.setMinimumSize(new java.awt.Dimension(70, 25));
        EOL.setPreferredSize(new java.awt.Dimension(60, 25));
        EOL.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                EOLItemStateChanged(evt);
            }
        });

        CR.setSelected(true);
        CR.setText("CR");
        CR.setToolTipText("在行尾增加CR");
        CR.setAlignmentY(0.0F);
        CR.setEnabled(false);
        CR.setIconTextGap(0);
        CR.setMargin(new java.awt.Insets(0, 0, 0, 0));
        CR.setName(""); // NOI18N
        CR.setNextFocusableComponent(Command);

        LF.setSelected(true);
        LF.setText("LF");
        LF.setToolTipText("在行尾加上LF");
        LF.setAlignmentY(0.0F);
        LF.setEnabled(false);
        LF.setIconTextGap(0);
        LF.setMargin(new java.awt.Insets(0, 0, 0, 0));

        DonateSmall.setText("捐赠");
        DonateSmall.setToolTipText("捐赠给开发者");
        DonateSmall.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        DonateSmall.setMargin(new java.awt.Insets(2, 2, 2, 2));
        DonateSmall.setMaximumSize(new java.awt.Dimension(100, 35));
        DonateSmall.setMinimumSize(new java.awt.Dimension(100, 35));
        DonateSmall.setPreferredSize(new java.awt.Dimension(100, 35));
        DonateSmall.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DonateSmallActionPerformed(evt);
            }
        });

        TerminalOnlyCheckBox.setText(" 隐藏编辑器");
        TerminalOnlyCheckBox.setAlignmentY(0.0F);
        TerminalOnlyCheckBox.setIconTextGap(0);
        TerminalOnlyCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
        TerminalOnlyCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                TerminalOnlyCheckBoxItemStateChanged(evt);
            }
        });

        EditorOnlyCheckBox.setText(" 隐藏终端");
        EditorOnlyCheckBox.setAlignmentY(0.0F);
        EditorOnlyCheckBox.setIconTextGap(0);
        EditorOnlyCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
        EditorOnlyCheckBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                EditorOnlyCheckBoxItemStateChanged(evt);
            }
        });

        LEDPanel.setLayer(PortOpenLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(PortCTS, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(PortDTR, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(PortRTS, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(Open, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(Speed, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(ReScan, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(AutoScroll, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(Port, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(EOL, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(CR, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(LF, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(DonateSmall, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(TerminalOnlyCheckBox, javax.swing.JLayeredPane.DEFAULT_LAYER);
        LEDPanel.setLayer(EditorOnlyCheckBox, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout LEDPanelLayout = new javax.swing.GroupLayout(LEDPanel);
        LEDPanel.setLayout(LEDPanelLayout);
        LEDPanelLayout.setHorizontalGroup(
            LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(LEDPanelLayout.createSequentialGroup()
                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(LEDPanelLayout.createSequentialGroup()
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(LEDPanelLayout.createSequentialGroup()
                                .addComponent(PortDTR)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(PortRTS))
                            .addGroup(LEDPanelLayout.createSequentialGroup()
                                .addComponent(PortOpenLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(PortCTS, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(Open, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(LEDPanelLayout.createSequentialGroup()
                                .addComponent(ReScan, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addGroup(LEDPanelLayout.createSequentialGroup()
                                        .addComponent(EOL, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                        .addComponent(LF))
                                    .addGroup(LEDPanelLayout.createSequentialGroup()
                                        .addComponent(AutoScroll, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(CR)))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(TerminalOnlyCheckBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(EditorOnlyCheckBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                            .addGroup(LEDPanelLayout.createSequentialGroup()
                                .addComponent(Speed, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(DonateSmall, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGap(0, 154, Short.MAX_VALUE))
                    .addComponent(Port, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        LEDPanelLayout.setVerticalGroup(
            LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(LEDPanelLayout.createSequentialGroup()
                .addComponent(Port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, LEDPanelLayout.createSequentialGroup()
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(ReScan, javax.swing.GroupLayout.DEFAULT_SIZE, 42, Short.MAX_VALUE)
                            .addGroup(LEDPanelLayout.createSequentialGroup()
                                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(AutoScroll, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(CR)
                                    .addComponent(TerminalOnlyCheckBox))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(EOL, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(LF)
                                    .addComponent(EditorOnlyCheckBox))))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(Speed, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(DonateSmall, javax.swing.GroupLayout.DEFAULT_SIZE, 45, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, LEDPanelLayout.createSequentialGroup()
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(PortOpenLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(PortCTS, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(LEDPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(PortDTR)
                            .addComponent(PortRTS)))
                    .addComponent(Open, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        Port.getAccessibleContext().setAccessibleName("");

        RightBasePane.add(LEDPanel);

        RightBigPane.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        RightBigPane.setOpaque(true);
        RightBigPane.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                RightBigPanePropertyChange(evt);
            }
        });

        RightFilesSplitPane.setDividerLocation(300);
        RightFilesSplitPane.setAutoscrolls(true);
        RightFilesSplitPane.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                RightFilesSplitPanePropertyChange(evt);
            }
        });

        RightSplitPane.setBorder(null);
        RightSplitPane.setDividerLocation(320);
        RightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        RightSplitPane.setName(""); // NOI18N
        RightSplitPane.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                RightSplitPanePropertyChange(evt);
            }
        });

        TerminalPane.setToolTipText("终端窗口");
        TerminalPane.setMaximumSize(new java.awt.Dimension(100, 100));
        TerminalPane.setMinimumSize(new java.awt.Dimension(100, 100));
        TerminalPane.setName(""); // NOI18N
        TerminalPane.setPreferredSize(new java.awt.Dimension(100, 100));
        TerminalPane.setViewportView(Terminal);

        Terminal.setEditable(false);
        Terminal.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        Terminal.setColumns(20);
        Terminal.setRows(50);
        Terminal.setTabSize(4);
        Terminal.setWrapStyleWord(false);
        Terminal.setBracketMatchingEnabled(false);
        Terminal.setCloseCurlyBraces(false);
        Terminal.setCloseMarkupTags(false);
        Terminal.setDragEnabled(false);
        Terminal.setFadeCurrentLineHighlight(true);
        Terminal.setHighlightSecondaryLanguages(false);
        Terminal.setMaximumSize(new java.awt.Dimension(100, 100));
        Terminal.setMinimumSize(new java.awt.Dimension(100, 100));
        Terminal.setName(""); // NOI18N
        Terminal.setPopupMenu(ContextMenuTerminal);
        Terminal.setSyntaxEditingStyle("text/LUA");
        Terminal.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                TerminalPropertyChange(evt);
            }
        });
        TerminalPane.setViewportView(Terminal);
        Terminal.getAccessibleContext().setAccessibleParent(TerminalPane);

        RightSplitPane.setTopComponent(TerminalPane);

        ScrollLog.setBorder(TerminalPane.getBorder());
        ScrollLog.setToolTipText("日志");
        ScrollLog.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        ScrollLog.setAlignmentX(0.0F);
        ScrollLog.setAlignmentY(0.0F);

        Log.setEditable(false);
        Log.setBackground(new java.awt.Color(51, 51, 51));
        Log.setColumns(20);
        Log.setFont(Log.getFont().deriveFont(Log.getFont().getSize()-1f));
        Log.setForeground(new java.awt.Color(0, 204, 0));
        Log.setLineWrap(true);
        Log.setRows(3);
        Log.setTabSize(4);
        Log.setText("启用日志");
        Log.setToolTipText("日志");
        Log.setWrapStyleWord(true);
        Log.setAlignmentX(0.0F);
        Log.setAlignmentY(0.0F);
        Log.setBorder(Terminal.getBorder());
        Log.setComponentPopupMenu(ContextMenuLog);
        Log.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        Log.setName("Log"); // NOI18N
        Log.setNextFocusableComponent(SendCommand);
        Log.setSelectionColor(new java.awt.Color(204, 0, 0));
        Log.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                LogCaretUpdate(evt);
            }
        });
        ScrollLog.setViewportView(Log);
        Log.getAccessibleContext().setAccessibleName("日志");

        RightSplitPane.setBottomComponent(ScrollLog);

        TerminalLogPane.setLayer(RightSplitPane, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout TerminalLogPaneLayout = new javax.swing.GroupLayout(TerminalLogPane);
        TerminalLogPane.setLayout(TerminalLogPaneLayout);
        TerminalLogPaneLayout.setHorizontalGroup(
            TerminalLogPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 293, Short.MAX_VALUE)
            .addGroup(TerminalLogPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(RightSplitPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE))
        );
        TerminalLogPaneLayout.setVerticalGroup(
            TerminalLogPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 339, Short.MAX_VALUE)
            .addGroup(TerminalLogPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(RightSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE))
        );

        RightFilesSplitPane.setLeftComponent(TerminalLogPane);

        FileManagerScrollPane.setBorder(null);
        FileManagerScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        FileManagersLayer.setMaximumSize(new java.awt.Dimension(145, 145));

        NodeFileManagerPane.setComponentPopupMenu(ContextMenuFileManager);
        NodeFileManagerPane.setMaximumSize(new java.awt.Dimension(145, 145));
        NodeFileManagerPane.setName(""); // NOI18N
        NodeFileManagerPane.setPreferredSize(new java.awt.Dimension(145, 145));
        java.awt.FlowLayout flowLayout1 = new java.awt.FlowLayout(java.awt.FlowLayout.LEADING, 2, 2);
        flowLayout1.setAlignOnBaseline(true);
        NodeFileManagerPane.setLayout(flowLayout1);

        FileFormat.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file manager (delete).png"))); // NOI18N
        FileFormat.setText("格式化");
        FileFormat.setToolTipText("格式化(删除)NodeMCU文件系统。所有文件将被删除！");
        FileFormat.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileFormat.setMargin(new java.awt.Insets(2, 4, 2, 4));
        FileFormat.setMaximumSize(new java.awt.Dimension(130, 25));
        FileFormat.setMinimumSize(new java.awt.Dimension(130, 25));
        FileFormat.setPreferredSize(new java.awt.Dimension(130, 25));
        FileFormat.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileFormatActionPerformed(evt);
            }
        });
        NodeFileManagerPane.add(FileFormat);

        FileSystemInfo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file manager.png"))); // NOI18N
        FileSystemInfo.setText("闪存用量");
        FileSystemInfo.setToolTipText("执行file.fsinfo()命令并显示ESP文件系统上的全部、已用和剩余空间");
        FileSystemInfo.setAlignmentX(0.5F);
        FileSystemInfo.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileSystemInfo.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileSystemInfo.setMaximumSize(new java.awt.Dimension(130, 25));
        FileSystemInfo.setPreferredSize(new java.awt.Dimension(130, 25));
        FileSystemInfo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileSystemInfoActionPerformed(evt);
            }
        });
        NodeFileManagerPane.add(FileSystemInfo);

        FileListReload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/refresh3.png"))); // NOI18N
        FileListReload.setText("重载");
        FileListReload.setAlignmentX(0.5F);
        FileListReload.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileListReload.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileListReload.setMaximumSize(new java.awt.Dimension(130, 25));
        FileListReload.setPreferredSize(new java.awt.Dimension(130, 25));
        FileListReload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileListReloadActionPerformed(evt);
            }
        });
        NodeFileManagerPane.add(FileListReload);

        FileAsButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file.png"))); // NOI18N
        FileAsButton1.setText("文件 1");
        FileAsButton1.setToolTipText("左单击");
        FileAsButton1.setAlignmentX(0.5F);
        FileAsButton1.setComponentPopupMenu(ContextMenuESPFileLUA);
        FileAsButton1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        FileAsButton1.setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileAsButton1.setMaximumSize(new java.awt.Dimension(130, 25));
        FileAsButton1.setPreferredSize(new java.awt.Dimension(130, 25));
        FileAsButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                FileAsButton1MouseClicked(evt);
            }
        });
        FileAsButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileAsButton1ActionPerformed(evt);
            }
        });
        NodeFileManagerPane.add(FileAsButton1);

        FileRenamePanel.setMaximumSize(new java.awt.Dimension(130, 45));
        FileRenamePanel.setMinimumSize(new java.awt.Dimension(130, 45));

        FileRenameLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        FileRenameLabel.setText("原文件名");
        FileRenameLabel.setToolTipText("输入新文件名并按回车完成或按重载取消");
        FileRenameLabel.setMaximumSize(new java.awt.Dimension(130, 14));
        FileRenameLabel.setMinimumSize(new java.awt.Dimension(130, 14));
        FileRenameLabel.setPreferredSize(new java.awt.Dimension(130, 14));

        FileRename.setText("新文件名");
        FileRename.setToolTipText("输入新文件名并按回车完成或按重载取消");
        FileRename.setMaximumSize(new java.awt.Dimension(130, 25));
        FileRename.setMinimumSize(new java.awt.Dimension(130, 25));
        FileRename.setPreferredSize(new java.awt.Dimension(130, 25));
        FileRename.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileRenameActionPerformed(evt);
            }
        });

        FileRenamePanel.setLayer(FileRenameLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
        FileRenamePanel.setLayer(FileRename, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout FileRenamePanelLayout = new javax.swing.GroupLayout(FileRenamePanel);
        FileRenamePanel.setLayout(FileRenamePanelLayout);
        FileRenamePanelLayout.setHorizontalGroup(
            FileRenamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FileRenamePanelLayout.createSequentialGroup()
                .addGroup(FileRenamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(FileRename, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(FileRenameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
        FileRenamePanelLayout.setVerticalGroup(
            FileRenamePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FileRenamePanelLayout.createSequentialGroup()
                .addComponent(FileRenameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(FileRename, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
        );

        NodeFileManagerPane.add(FileRenamePanel);

        PyFileManagerPane.setMaximumSize(new java.awt.Dimension(500, 155));
        PyFileManagerPane.setMinimumSize(new java.awt.Dimension(55, 55));
        PyFileManagerPane.setPreferredSize(new java.awt.Dimension(155, 155));
        PyFileManagerPane.setLayout(new java.awt.FlowLayout());

        PyListDir.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/refresh3.png"))); // NOI18N
        PyListDir.setText("文件列表 /");
        PyListDir.setToolTipText("执行listdir()命令并显示文件");
        PyListDir.setAlignmentX(0.5F);
        PyListDir.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        PyListDir.setMargin(new java.awt.Insets(2, 2, 2, 2));
        PyListDir.setMaximumSize(new java.awt.Dimension(130, 25));
        PyListDir.setPreferredSize(new java.awt.Dimension(130, 25));
        PyListDir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PyListDirActionPerformed(evt);
            }
        });
        PyFileManagerPane.add(PyListDir);

        PyFileAsButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file.png"))); // NOI18N
        PyFileAsButton1.setText("文件 1");
        PyFileAsButton1.setToolTipText("单击");
        PyFileAsButton1.setAlignmentX(0.5F);
        PyFileAsButton1.setComponentPopupMenu(ContextMenuESPFileLUA);
        PyFileAsButton1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        PyFileAsButton1.setMargin(new java.awt.Insets(2, 2, 2, 2));
        PyFileAsButton1.setMaximumSize(new java.awt.Dimension(130, 25));
        PyFileAsButton1.setPreferredSize(new java.awt.Dimension(130, 25));
        PyFileAsButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                PyFileAsButton1MouseClicked(evt);
            }
        });
        PyFileAsButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PyFileAsButton1ActionPerformed(evt);
            }
        });
        PyFileManagerPane.add(PyFileAsButton1);

        FileManagersLayer.setLayer(NodeFileManagerPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        FileManagersLayer.setLayer(PyFileManagerPane, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout FileManagersLayerLayout = new javax.swing.GroupLayout(FileManagersLayer);
        FileManagersLayer.setLayout(FileManagersLayerLayout);
        FileManagersLayerLayout.setHorizontalGroup(
            FileManagersLayerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FileManagersLayerLayout.createSequentialGroup()
                .addGroup(FileManagersLayerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(PyFileManagerPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(NodeFileManagerPane, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 433, Short.MAX_VALUE))
        );
        FileManagersLayerLayout.setVerticalGroup(
            FileManagersLayerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(FileManagersLayerLayout.createSequentialGroup()
                .addComponent(NodeFileManagerPane, javax.swing.GroupLayout.DEFAULT_SIZE, 255, Short.MAX_VALUE)
                .addGap(6, 6, 6)
                .addComponent(PyFileManagerPane, javax.swing.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE))
        );

        FileManagerScrollPane.setViewportView(FileManagersLayer);

        RightFilesSplitPane.setRightComponent(FileManagerScrollPane);

        RightSnippetsPane.setLayout(new java.awt.FlowLayout());

        ButtonSnippet0.setMnemonic(KeyEvent.VK_BACK_QUOTE);
        ButtonSnippet0.setText("片段 0");
        ButtonSnippet0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet0ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet0);

        ButtonSnippet1.setMnemonic(KeyEvent.VK_1);
        ButtonSnippet1.setText("片段 1");
        ButtonSnippet1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet1ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet1);

        ButtonSnippet2.setMnemonic(KeyEvent.VK_2);
        ButtonSnippet2.setText("片段 2");
        ButtonSnippet2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet2ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet2);

        ButtonSnippet3.setMnemonic(KeyEvent.VK_3);
        ButtonSnippet3.setText("片段 3");
        ButtonSnippet3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet3ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet3);

        ButtonSnippet4.setMnemonic(KeyEvent.VK_4);
        ButtonSnippet4.setText("片段 4");
        ButtonSnippet4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet4ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet4);

        ButtonSnippet5.setMnemonic(KeyEvent.VK_5);
        ButtonSnippet5.setText("片段 5");
        ButtonSnippet5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet5ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet5);

        ButtonSnippet6.setMnemonic(KeyEvent.VK_6);
        ButtonSnippet6.setText("片段 6");
        ButtonSnippet6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet6ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet6);

        ButtonSnippet7.setMnemonic(KeyEvent.VK_7);
        ButtonSnippet7.setText("片段 7");
        ButtonSnippet7.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet7ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet7);

        ButtonSnippet8.setMnemonic(KeyEvent.VK_8);
        ButtonSnippet8.setText("片段 8");
        ButtonSnippet8.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet8ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet8);

        ButtonSnippet9.setMnemonic(KeyEvent.VK_9);
        ButtonSnippet9.setText("片段 9");
        ButtonSnippet9.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet9ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet9);

        ButtonSnippet10.setMnemonic(KeyEvent.VK_0);
        ButtonSnippet10.setText("片段 10");
        ButtonSnippet10.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet10ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet10);

        ButtonSnippet11.setMnemonic(KeyEvent.VK_MINUS);
        ButtonSnippet11.setText("片段 11");
        ButtonSnippet11.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet11ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet11);

        ButtonSnippet12.setMnemonic(KeyEvent.VK_EQUALS);
        ButtonSnippet12.setText("片段 12");
        ButtonSnippet12.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet12ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet12);

        ButtonSnippet13.setMnemonic(KeyEvent.VK_BACK_SLASH);
        ButtonSnippet13.setText("片段 13");
        ButtonSnippet13.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet13ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet13);

        ButtonSnippet14.setMnemonic(KeyEvent.VK_BACK_SPACE);
        ButtonSnippet14.setText("片段 14");
        ButtonSnippet14.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet14ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet14);

        ButtonSnippet15.setText("片段 15");
        ButtonSnippet15.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonSnippet15ActionPerformed(evt);
            }
        });
        RightSnippetsPane.add(ButtonSnippet15);

        RightBigPane.setLayer(RightFilesSplitPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
        RightBigPane.setLayer(RightSnippetsPane, javax.swing.JLayeredPane.DEFAULT_LAYER);

        javax.swing.GroupLayout RightBigPaneLayout = new javax.swing.GroupLayout(RightBigPane);
        RightBigPane.setLayout(RightBigPaneLayout);
        RightBigPaneLayout.setHorizontalGroup(
            RightBigPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(RightFilesSplitPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addComponent(RightSnippetsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
        );
        RightBigPaneLayout.setVerticalGroup(
            RightBigPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(RightBigPaneLayout.createSequentialGroup()
                .addComponent(RightFilesSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(RightSnippetsPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE))
        );

        RightBasePane.add(RightBigPane);

        RightExtraButtons.setOpaque(true);
        RightExtraButtons.setLayout(new java.awt.FlowLayout());

        NodeHeap.setText("堆大小");
        NodeHeap.setToolTipText("返回剩余堆大小(以字节为单位)");
        NodeHeap.setMaximumSize(new java.awt.Dimension(87, 30));
        NodeHeap.setMinimumSize(new java.awt.Dimension(87, 30));
        NodeHeap.setPreferredSize(new java.awt.Dimension(87, 30));
        NodeHeap.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NodeHeapActionPerformed(evt);
            }
        });
        RightExtraButtons.add(NodeHeap);

        NodeInfo.setText("芯片信息");
        NodeInfo.setToolTipText("返回NodeMCU版本，芯片ID, 闪存ID, 闪存大小，闪存模式和闪存速度");
        NodeInfo.setMaximumSize(new java.awt.Dimension(87, 30));
        NodeInfo.setMinimumSize(new java.awt.Dimension(87, 30));
        NodeInfo.setPreferredSize(new java.awt.Dimension(87, 30));
        NodeInfo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NodeInfoActionPerformed(evt);
            }
        });
        RightExtraButtons.add(NodeInfo);

        NodeChipID.setText("芯片ID");
        NodeChipID.setToolTipText("返回芯片ID");
        NodeChipID.setMargin(new java.awt.Insets(2, 2, 2, 2));
        NodeChipID.setMaximumSize(new java.awt.Dimension(87, 30));
        NodeChipID.setMinimumSize(new java.awt.Dimension(87, 30));
        NodeChipID.setPreferredSize(new java.awt.Dimension(87, 30));
        NodeChipID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NodeChipIDActionPerformed(evt);
            }
        });
        RightExtraButtons.add(NodeChipID);

        NodeFlashID.setText("闪存ID");
        NodeFlashID.setToolTipText("返回闪存ID");
        NodeFlashID.setMargin(new java.awt.Insets(2, 2, 2, 2));
        NodeFlashID.setMaximumSize(new java.awt.Dimension(87, 30));
        NodeFlashID.setMinimumSize(new java.awt.Dimension(87, 30));
        NodeFlashID.setPreferredSize(new java.awt.Dimension(87, 30));
        NodeFlashID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NodeFlashIDActionPerformed(evt);
            }
        });
        RightExtraButtons.add(NodeFlashID);

        NodeReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/reset.png"))); // NOI18N
        NodeReset.setText("重启");
        NodeReset.setToolTipText("通过命令node.reset()进行软重置");
        NodeReset.setMargin(new java.awt.Insets(2, 4, 2, 4));
        NodeReset.setMaximumSize(new java.awt.Dimension(87, 30));
        NodeReset.setMinimumSize(new java.awt.Dimension(87, 30));
        NodeReset.setPreferredSize(new java.awt.Dimension(87, 30));
        NodeReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NodeResetActionPerformed(evt);
            }
        });
        RightExtraButtons.add(NodeReset);

        RightBasePane.add(RightExtraButtons);

        RightBottomPane.setOpaque(true);
        RightBottomPane.setLayout(new java.awt.GridBagLayout());

        Command.setEditable(true);
        Command.setMaximumRowCount(20);
        Command.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "AT", "AT+GMR", "AT+RST", "" }));
        Command.setToolTipText("发送命令");
        Command.setAutoscrolls(true);
        Command.setEnabled(false);
        Command.setName("Command"); // NOI18N
        Command.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                CommandItemStateChanged(evt);
            }
        });
        Command.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CommandActionPerformed(evt);
            }
        });
        Command.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                CommandKeyTyped(evt);
            }
            public void keyPressed(java.awt.event.KeyEvent evt) {
                CommandKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                CommandKeyReleased(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipady = 10;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        RightBottomPane.add(Command, gridBagConstraints);
        Command.getAccessibleContext().setAccessibleName("Command");

        SendCommand.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/left.png"))); // NOI18N
        SendCommand.setText("发送");
        SendCommand.setAlignmentY(0.0F);
        SendCommand.setEnabled(false);
        SendCommand.setMargin(new java.awt.Insets(0, 0, 0, 0));
        SendCommand.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SendCommandActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipady = 10;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        RightBottomPane.add(SendCommand, gridBagConstraints);
        SendCommand.getAccessibleContext().setAccessibleName("");

        RightBasePane.add(RightBottomPane);

        HorizontSplit.setRightComponent(RightBasePane);

        MainMenuBar.setAlignmentX(0.0F);
        MainMenuBar.setName("MainMenu"); // NOI18N
        MainMenuBar.setPreferredSize(new java.awt.Dimension(300, 22));

        MenuFile.setText("文件");
        MenuFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuFileActionPerformed(evt);
            }
        });

        MenuItemFileNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/document.png"))); // NOI18N
        MenuItemFileNew.setText("新文件");
        MenuItemFileNew.setToolTipText("新建文件");
        MenuItemFileNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileNewActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileNew);

        MenuItemFileOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/folder open.png"))); // NOI18N
        MenuItemFileOpen.setText("打开文件");
        MenuItemFileOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileOpenActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileOpen);

        MenuItemFileReload.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileReload.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/refresh.png"))); // NOI18N
        MenuItemFileReload.setText("重新从磁盘载入");
        MenuItemFileReload.setToolTipText("如果使用外部编辑器，请从磁盘重新加载文件");
        MenuItemFileReload.setEnabled(false);
        MenuItemFileReload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileReloadActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileReload);

        MenuItemFileSave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save.png"))); // NOI18N
        MenuItemFileSave.setText("保存");
        MenuItemFileSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileSaveActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileSave);

        MenuItemFileSaveAs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save.png"))); // NOI18N
        MenuItemFileSaveAs.setText("保存全部");
        MenuItemFileSaveAs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileSaveAsActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileSaveAs);

        MenuItemFileSaveAll.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileSaveAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/save_all.png"))); // NOI18N
        MenuItemFileSaveAll.setText("保存全部到磁盘上");
        MenuItemFileSaveAll.setEnabled(false);
        MenuFile.add(MenuItemFileSaveAll);

        MenuItemFileClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemFileClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/folder closed.png"))); // NOI18N
        MenuItemFileClose.setText("关闭");
        MenuItemFileClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileCloseActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileClose);
        MenuFile.add(jSeparatorFileMenu);

        MenuItemFileSaveESP.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemFileSaveESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/move.png"))); // NOI18N
        MenuItemFileSaveESP.setText("保存到ESP");
        MenuItemFileSaveESP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileSaveESPActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileSaveESP);

        jMenuItem4.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.ALT_DOWN_MASK));
        jMenuItem4.setText("保存全部到ESP");
        jMenuItem4.setEnabled(false);
        MenuFile.add(jMenuItem4);

        MenuItemFileSendESP.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemFileSendESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/script_send.png"))); // NOI18N
        MenuItemFileSendESP.setText("发送到ESP");
        MenuItemFileSendESP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileSendESPActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileSendESP);

        jMenuItem7.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_U, java.awt.event.InputEvent.ALT_DOWN_MASK));
        jMenuItem7.setText("上传文件到ESP");
        jMenuItem7.setEnabled(false);
        MenuFile.add(jMenuItem7);
        MenuFile.add(jSeparator4);

        MenuItemFileDo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_D, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemFileDo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/play.png"))); // NOI18N
        MenuItemFileDo.setText("运行ESP上的文件");
        MenuItemFileDo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileDoActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileDo);
        MenuFile.add(jSeparator3);

        MenuItemFileRemoveESP.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemFileRemoveESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/trash.png"))); // NOI18N
        MenuItemFileRemoveESP.setText("从ESP上删除");
        MenuItemFileRemoveESP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileRemoveESPActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileRemoveESP);
        MenuFile.add(jSeparator2);

        MenuItemFileExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemFileExit.setText("退出");
        MenuItemFileExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemFileExitActionPerformed(evt);
            }
        });
        MenuFile.add(MenuItemFileExit);

        MainMenuBar.add(MenuFile);

        MenuEdit.setText("编辑");

        MenuItemEditUndo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditUndo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/undo1.png"))); // NOI18N
        MenuItemEditUndo.setText("撤销");
        MenuItemEditUndo.setEnabled(false);
        MenuItemEditUndo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditUndoActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditUndo);

        MenuItemEditRedo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, 0));
        MenuItemEditRedo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/redo1.png"))); // NOI18N
        MenuItemEditRedo.setText("重做");
        MenuItemEditRedo.setEnabled(false);
        MenuItemEditRedo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditRedoActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditRedo);
        MenuEdit.add(jSeparator7);

        MenuItemEditCut.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/cut.png"))); // NOI18N
        MenuItemEditCut.setText("剪切");
        MenuItemEditCut.setEnabled(false);
        MenuItemEditCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditCutActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditCut);

        MenuItemEditCopy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/copy.png"))); // NOI18N
        MenuItemEditCopy.setText("复制");
        MenuItemEditCopy.setEnabled(false);
        MenuItemEditCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditCopyActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditCopy);

        MenuItemEditPaste.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemEditPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/paste.png"))); // NOI18N
        MenuItemEditPaste.setText("粘贴");
        MenuItemEditPaste.setEnabled(false);
        MenuItemEditPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditPasteActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditPaste);
        MenuEdit.add(jSeparator5);

        MenuItemEditSendSelected.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditSendSelected.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/send_selected.png"))); // NOI18N
        MenuItemEditSendSelected.setText("发送选定块到ESP");
        MenuItemEditSendSelected.setToolTipText("将选定的块发送到ESP");
        MenuItemEditSendSelected.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditSendSelectedActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditSendSelected);

        MenuItemEditSendLine.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemEditSendLine.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/run_line.png"))); // NOI18N
        MenuItemEditSendLine.setText("发送当前行到ESP");
        MenuItemEditSendLine.setToolTipText("将当前行从代码编辑器窗口发送到ESP");
        MenuItemEditSendLine.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemEditSendLineActionPerformed(evt);
            }
        });
        MenuEdit.add(MenuItemEditSendLine);

        MainMenuBar.add(MenuEdit);

        MenuESP.setText("ESP");

        MenuItemESPReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/reset.png"))); // NOI18N
        MenuItemESPReset.setText("重启ESP模块");
        MenuItemESPReset.setToolTipText("发送RESET命令(固件依赖)");
        MenuItemESPReset.setEnabled(false);
        MenuItemESPReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemESPResetActionPerformed(evt);
            }
        });
        MenuESP.add(MenuItemESPReset);

        MenuItemESPFormat.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file manager (delete).png"))); // NOI18N
        MenuItemESPFormat.setText("格式化ESP");
        MenuItemESPFormat.setToolTipText("删除ESP闪存内存中的所有文件");
        MenuItemESPFormat.setEnabled(false);
        MenuItemESPFormat.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemESPFormatActionPerformed(evt);
            }
        });
        MenuESP.add(MenuItemESPFormat);

        MainMenuBar.add(MenuESP);

        MenuView.setText("视图");
        buttonGroupLF.add(MenuView);
        MenuView.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuViewActionPerformed(evt);
            }
        });

        AlwaysOnTop.setText("总是置顶");
        AlwaysOnTop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/AlwaysOnTop.png"))); // NOI18N
        AlwaysOnTop.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                AlwaysOnTopItemStateChanged(evt);
            }
        });
        AlwaysOnTop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AlwaysOnTopActionPerformed(evt);
            }
        });
        MenuView.add(AlwaysOnTop);

        MenuItemViewLog.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewLog.setSelected(true);
        MenuItemViewLog.setText("显示日志");
        MenuItemViewLog.setToolTipText("启用/禁用日志窗口");
        MenuItemViewLog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/backup.png"))); // NOI18N
        MenuItemViewLog.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewLogItemStateChanged(evt);
            }
        });
        MenuItemViewLog.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewLogActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewLog);

        MenuItemViewClearLog.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewClearLog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/backup_delete.png"))); // NOI18N
        MenuItemViewClearLog.setText("清空日志");
        MenuItemViewClearLog.setToolTipText("清空日志窗口");
        MenuItemViewClearLog.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewClearLogActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewClearLog);

        MenuItemViewClearTerminal.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F2, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewClearTerminal.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/terminal_clear.png"))); // NOI18N
        MenuItemViewClearTerminal.setText("清空终端");
        MenuItemViewClearTerminal.setToolTipText("清空终端窗口");
        MenuItemViewClearTerminal.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewClearTerminalActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewClearTerminal);
        MenuView.add(jSeparator9);

        MenuItemViewTerminalOnly.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemViewTerminalOnly.setText("仅显示终端(左面板显示/隐藏)");
        MenuItemViewTerminalOnly.setToolTipText("启用/禁用左面板");
        MenuItemViewTerminalOnly.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewTerminalOnlyItemStateChanged(evt);
            }
        });
        MenuItemViewTerminalOnly.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewTerminalOnlyActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewTerminalOnly);

        MenuItemViewEditorOnly.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F2, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemViewEditorOnly.setText("仅显示编辑器(右面板显示/隐藏)");
        MenuItemViewEditorOnly.setToolTipText("启用/禁用右面板");
        MenuItemViewEditorOnly.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewEditorOnlyItemStateChanged(evt);
            }
        });
        MenuItemViewEditorOnly.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewEditorOnlyActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewEditorOnly);
        MenuView.add(jSeparator18);

        MenuItemViewToolbar.setSelected(true);
        MenuItemViewToolbar.setText("在左上角显示工具栏");
        MenuItemViewToolbar.setToolTipText("启用/禁用文件工具栏在左上角");
        MenuItemViewToolbar.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewToolbarItemStateChanged(evt);
            }
        });
        MenuItemViewToolbar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewToolbarActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewToolbar);

        MenuItemViewLeftExtra.setText("在左边显示额外的按钮");
        MenuItemViewLeftExtra.setToolTipText("启用/禁用左边的额外按钮面板");
        MenuItemViewLeftExtra.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewLeftExtraItemStateChanged(evt);
            }
        });
        MenuItemViewLeftExtra.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewLeftExtraActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewLeftExtra);

        MenuItemViewSnippets.setSelected(true);
        MenuItemViewSnippets.setText("在右边显示片段面板");
        MenuItemViewSnippets.setToolTipText("启用/禁用片段面板");
        MenuItemViewSnippets.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewSnippetsItemStateChanged(evt);
            }
        });
        MenuItemViewSnippets.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewSnippetsActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewSnippets);

        MenuItemViewFileManager.setSelected(true);
        MenuItemViewFileManager.setText("在右边显示文件管理面板");
        MenuItemViewFileManager.setToolTipText("启用/禁用文件管理器面板在右边");
        MenuItemViewFileManager.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewFileManagerItemStateChanged(evt);
            }
        });
        MenuItemViewFileManager.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewFileManagerActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewFileManager);

        MenuItemViewRightExtra.setSelected(true);
        MenuItemViewRightExtra.setText("在右下角显示额外的按钮");
        MenuItemViewRightExtra.setToolTipText("启用/禁用右下角的额外按钮面板");
        MenuItemViewRightExtra.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewRightExtraItemStateChanged(evt);
            }
        });
        MenuItemViewRightExtra.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewRightExtraActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewRightExtra);

        MenuItemViewDonate.setSelected(true);
        MenuItemViewDonate.setText("隐藏构建按钮");
        MenuItemViewDonate.setToolTipText("启用/禁用构建按钮");
        MenuItemViewDonate.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                MenuItemViewDonateItemStateChanged(evt);
            }
        });
        MenuItemViewDonate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewDonateActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewDonate);
        MenuView.add(jSeparator13);

        MenuItemViewTermFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewTermFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemViewTermFontInc.setText("终端字体 +");
        MenuItemViewTermFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewTermFontIncActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewTermFontInc);

        MenuItemViewTermFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewTermFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemViewTermFontDec.setText("终端字体 -");
        MenuItemViewTermFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewTermFontDecActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewTermFontDec);
        MenuView.add(jSeparator10);

        MenuItemViewEditorFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemViewEditorFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemViewEditorFontInc.setText("编辑器字体 +");
        MenuItemViewEditorFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewEditorFontIncActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewEditorFontInc);

        MenuItemViewEditorFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.ALT_DOWN_MASK));
        MenuItemViewEditorFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemViewEditorFontDec.setText("编辑器字体 -");
        MenuItemViewEditorFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewEditorFontDecActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewEditorFontDec);
        MenuView.add(jSeparator11);

        MenuItemViewLogFontInc.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ADD, java.awt.event.InputEvent.ALT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewLogFontInc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom in.png"))); // NOI18N
        MenuItemViewLogFontInc.setText("日志字体 +");
        MenuItemViewLogFontInc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewLogFontIncActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewLogFontInc);

        MenuItemViewLogFontDec.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SUBTRACT, java.awt.event.InputEvent.ALT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK));
        MenuItemViewLogFontDec.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/zoom out.png"))); // NOI18N
        MenuItemViewLogFontDec.setText("日志字体 -");
        MenuItemViewLogFontDec.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewLogFontDecActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewLogFontDec);
        MenuView.add(jSeparator12);

        MenuItemViewFontDefault.setText("重置所有字体大小为默认值");
        MenuItemViewFontDefault.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemViewFontDefaultActionPerformed(evt);
            }
        });
        MenuView.add(MenuItemViewFontDefault);
        MenuView.add(jSeparator17);

        MainMenuBar.add(MenuView);

        MenuLinks.setText("链接");

        MenuItemLinksMicroPythonDoc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/micropython.png"))); // NOI18N
        MenuItemLinksMicroPythonDoc.setText("MicroPython英文文档");
        MenuItemLinksMicroPythonDoc.setToolTipText("在浏览器中打开API文档");
        MenuItemLinksMicroPythonDoc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksMicroPythonDocActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksMicroPythonDoc);

        MenuItemLinksNodeMCUdoc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/nodemcu.png"))); // NOI18N
        MenuItemLinksNodeMCUdoc.setText("NodeMCU英文文档");
        MenuItemLinksNodeMCUdoc.setToolTipText("在浏览器中打开NodeMCU API英文文档");
        MenuItemLinksNodeMCUdoc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksNodeMCUdocActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksNodeMCUdoc);
        MenuLinks.add(jSeparator15);

        MenuItemLinksBuyDevBoard.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/aliexpress.png"))); // NOI18N
        MenuItemLinksBuyDevBoard.setText("购买NodeMCU v3 (LoLin品牌，USB)");
        MenuItemLinksBuyDevBoard.setToolTipText("在全球速卖通上购买NodeMCU开发板");
        MenuItemLinksBuyDevBoard.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksBuyDevBoardActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksBuyDevBoard);

        MenuItemLinksBuyESP8266.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/aliexpress.png"))); // NOI18N
        MenuItemLinksBuyESP8266.setText("购买Witty (RGB LED, 3个按钮，USB)");
        MenuItemLinksBuyESP8266.setToolTipText("购买ESP8266 ESP-01 ESP-02…全球速卖通的ESP-12模块");
        MenuItemLinksBuyESP8266.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksBuyESP8266ActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksBuyESP8266);

        MenuItemLinksBuyESD12.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/aliexpress.png"))); // NOI18N
        MenuItemLinksBuyESD12.setText("购买WeMos mini(多屏蔽，USB)");
        MenuItemLinksBuyESD12.setToolTipText("购买ESP8266 ESD-12 4M闪存板");
        MenuItemLinksBuyESD12.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksBuyESD12ActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksBuyESD12);

        MenuItemLinksBuyOther.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/aliexpress.png"))); // NOI18N
        MenuItemLinksBuyOther.setText("购买最流行的DIY部件");
        MenuItemLinksBuyOther.setToolTipText("在全球速卖通上购买任何电子产品和其他产品");
        MenuItemLinksBuyOther.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksBuyOtherActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksBuyOther);
        MenuLinks.add(jSeparator16);

        MenuItemLinksIoTmanager.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/IoTmanager.png"))); // NOI18N
        MenuItemLinksIoTmanager.setText("物联网管理-免费的Android应用程序，为任何DIY设备。免费广告。来自4refr0nt, ESPlorer开发者");
        MenuItemLinksIoTmanager.setToolTipText("你可以为ESPlorer开发者捐款");
        MenuItemLinksIoTmanager.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksIoTmanagerActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksIoTmanager);
        MenuLinks.add(jSeparator19);

        MenuItemLinksESPlorerForumEn.setText("ESPlorer讨论，bug报告 英语");
        MenuItemLinksESPlorerForumEn.setToolTipText("链接到ESP8266.COM论坛，ESPlorer主题，英语");
        MenuItemLinksESPlorerForumEn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksESPlorerForumEnActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksESPlorerForumEn);

        MenuItemLinksESPlorerForumRu.setText("ESPlorer讨论，bug报告 俄语");
        MenuItemLinksESPlorerForumRu.setToolTipText("ESP8266链接。俄罗斯论坛，ESPlorer主题，俄语");
        MenuItemLinksESPlorerForumRu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksESPlorerForumRuActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksESPlorerForumRu);

        MenuItemLinksESPlorerLatest.setText("下载最新的稳定版");
        MenuItemLinksESPlorerLatest.setToolTipText("ESP8266链接。RU，下载ESPlorer最新版本");
        MenuItemLinksESPlorerLatest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksESPlorerLatestActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksESPlorerLatest);

        MenuItemLinksESPlorerSource.setText("从GitHub上下载ESPlorer的源码");
        MenuItemLinksESPlorerSource.setToolTipText("链接到GITHUB下载ESPlorer源代码");
        MenuItemLinksESPlorerSource.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksESPlorerSourceActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksESPlorerSource);

        MenuItemLinksESPlorerHome.setText("ESPlorer主页");
        MenuItemLinksESPlorerHome.setToolTipText("ESP8266链接，ESPlorer主页，俄文");
        MenuItemLinksESPlorerHome.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksESPlorerHomeActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksESPlorerHome);
        MenuLinks.add(jSeparator20);

        MenuItemLinksDonate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/paypal.png"))); // NOI18N
        MenuItemLinksDonate.setText("为ESPlorer开发者捐款");
        MenuItemLinksDonate.setToolTipText("你可以为ESPlorer开发者捐款");
        MenuItemLinksDonate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemLinksDonateActionPerformed(evt);
            }
        });
        MenuLinks.add(MenuItemLinksDonate);

        MainMenuBar.add(MenuLinks);

        MenuHelp.setText("帮助");

        MenuItemHelpAbout.setText("关于");
        MenuItemHelpAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuItemHelpAboutActionPerformed(evt);
            }
        });
        MenuHelp.add(MenuItemHelpAbout);

        MainMenuBar.add(MenuHelp);

        setJMenuBar(MainMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(HorizontSplit, javax.swing.GroupLayout.DEFAULT_SIZE, 1112, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(HorizontSplit, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
        );

        getAccessibleContext().setAccessibleDescription("");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void PortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PortActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_PortActionPerformed

    private void MenuItemFileExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileExitActionPerformed
        AppClose();
    }//GEN-LAST:event_MenuItemFileExitActionPerformed

    private void SpeedFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_SpeedFocusLost
        nSpeed = Integer.parseInt((String) Speed.getSelectedItem());
    }//GEN-LAST:event_SpeedFocusLost

    private void SpeedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SpeedActionPerformed
        if (portJustOpen) {
            log("错误：与MCU未建立通信。");
            return;
        }
        nSpeed = Integer.parseInt((String) Speed.getSelectedItem());
        if (pOpen) { // reconnect
            if (OptionNodeMCU.isSelected() || FirmwareType == FIRMWARE_NODEMCU) {
                log("尝试重新连接波特 " + Integer.toString(nSpeed) + "...");
                btnSend("print(uart.setup(0, " + nSpeed + ", 8, 0, 1, 1 ))");
                try {
                    Thread.sleep(200L);
                } catch (InterruptedException e) {
                }
            } else {
                return;
            }
            if (SetSerialPortParams()) {
                log("重连：成功！");
                CheckComm();
            }
        }
        UpdateLED();
    }//GEN-LAST:event_SpeedActionPerformed

    private void OpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OpenActionPerformed
        if (Open.isSelected()) {
            if (pOpen) {
                return;
            }
            try {
                String port;
                if (UseCustomPortName.isSelected()) {
                    port = CustomPortName.getText().trim();
                } else {
                    port = Port.getSelectedItem().toString().trim();
                }
                prefs.put(SERIAL_PORT, port);
                log("默认串口" + port + "已保存。");
                int speed = Speed.getSelectedIndex();
                prefs.putInt(SERIAL_BAUD, speed);
                log("默认波特率" + Speed.getSelectedItem().toString().trim() + "已保存。");
            } catch (Exception e) {
            }
            pOpen = portOpen();
            Open.setSelected(pOpen);
        } else {
            portClose();
        }
        UpdateButtons();
    }//GEN-LAST:event_OpenActionPerformed
    private void UpdateButtons() {
        pOpen = Open.isSelected();
        if (pOpen && !portJustOpen) {
            UpdateLED();
            Port.setEnabled(false);
            //Speed.setEnabled(false);
            ReScan.setEnabled(false);
            SendCommand.setEnabled(true);
            Command.setEnabled(true);
            CR.setEnabled(true);
            LF.setEnabled(true);
            // left panel
            FileSaveESP.setEnabled(true);
            MenuItemFileSaveESP.setEnabled(true);
            FileSendESP.setEnabled(true);
            MenuItemFileSendESP.setEnabled(true);
            MenuItemFileRemoveESP.setEnabled(true);
            FileDo.setEnabled(true);
            MenuItemFileDo.setEnabled(true);
            MenuItemEditorSendLine.setEnabled(true);
            MenuItemEditSendLine.setEnabled(true);
            ButtonSendLine.setEnabled(true);
            NodeReset.setEnabled(true);
            MenuItemTerminalReset.setEnabled(true);
            MenuItemTerminalFormat.setEnabled(true);
            MenuItemESPReset.setEnabled(true);
            MenuItemESPFormat.setEnabled(true);
            SnippetRun.setEnabled(true);
            ButtonSendLine.setEnabled(true);
            ButtonSnippet0.setEnabled(true);
            ButtonSnippet1.setEnabled(true);
            ButtonSnippet2.setEnabled(true);
            ButtonSnippet3.setEnabled(true);
            ButtonSnippet4.setEnabled(true);
            ButtonSnippet5.setEnabled(true);
            ButtonSnippet6.setEnabled(true);
            ButtonSnippet7.setEnabled(true);
            ButtonSnippet8.setEnabled(true);
            ButtonSnippet9.setEnabled(true);
            ButtonSnippet10.setEnabled(true);
            ButtonSnippet11.setEnabled(true);
            ButtonSnippet12.setEnabled(true);
            ButtonSnippet13.setEnabled(true);
            ButtonSnippet14.setEnabled(true);
            ButtonSnippet15.setEnabled(true);

        } else {
            UpdateLED();
            Port.setEnabled(true);
            //Speed.setEnabled(true);
            ReScan.setEnabled(true);
            SendCommand.setEnabled(false);
            Command.setEnabled(false);
            CR.setEnabled(false);
            LF.setEnabled(false);
            // left panel
            FileSaveESP.setEnabled(false);
            FileSaveESP.setSelected(false);
            MenuItemFileSaveESP.setEnabled(false);
            FileSendESP.setEnabled(false);
            FileSendESP.setSelected(false);
            MenuItemFileSendESP.setEnabled(false);
            MenuItemFileRemoveESP.setEnabled(false);
            FileDo.setEnabled(false);
            MenuItemFileDo.setEnabled(false);
            MenuItemEditorSendLine.setEnabled(false);
            MenuItemEditSendLine.setEnabled(false);
            ButtonSendLine.setEnabled(false);
            NodeReset.setEnabled(false);
            MenuItemTerminalReset.setEnabled(false);
            MenuItemTerminalFormat.setEnabled(false);
            MenuItemESPReset.setEnabled(false);
            MenuItemESPFormat.setEnabled(false);
            SnippetRun.setEnabled(false);
            ButtonSnippet0.setEnabled(false);
            ButtonSnippet1.setEnabled(false);
            ButtonSnippet2.setEnabled(false);
            ButtonSnippet3.setEnabled(false);
            ButtonSnippet4.setEnabled(false);
            ButtonSnippet5.setEnabled(false);
            ButtonSnippet6.setEnabled(false);
            ButtonSnippet7.setEnabled(false);
            ButtonSnippet8.setEnabled(false);
            ButtonSnippet9.setEnabled(false);
            ButtonSnippet10.setEnabled(false);
            ButtonSnippet11.setEnabled(false);
            ButtonSnippet12.setEnabled(false);
            ButtonSnippet13.setEnabled(false);
            ButtonSnippet14.setEnabled(false);
            ButtonSnippet15.setEnabled(false);
        }

        DisablingNotImplemented();

    }
    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        PortFinder();
        this.setTitle("ESPlorer " + VERSION + " by 4refr0nt 汉化：Minuy");
        ProgressBar.setVisible(false);
        CommandsSetNodeMCU();
        isToolbarShow();
        isLeftExtraShow();
        isRightExtraShow();
        isRightSnippetsShow();
        SetWindowSize();
        isFileManagerShow();
        isLogShow();
    }//GEN-LAST:event_formWindowOpened
    private void SetWindowSize() {
        int x, y, h, w;
        x = prefs.getInt(WIN_X, 0);
        y = prefs.getInt(WIN_Y, 0);
        h = prefs.getInt(WIN_H, 768);
        w = prefs.getInt(WIN_W, 1024);
        this.setBounds(x, y, w, h);
    }

    private void isToolbarShow() {
        FilesToolBar.setVisible(MenuItemViewToolbar.isSelected());
    }

    private void isLeftExtraShow() {
        LeftExtraButtons.setVisible(MenuItemViewLeftExtra.isSelected());
    }

    private void isRightExtraShow() {
        RightExtraButtons.setVisible(MenuItemViewRightExtra.isSelected());
    }

    private void isRightSnippetsShow() {
        RightSnippetsPane.setVisible(MenuItemViewSnippets.isSelected());
    }

    private void isFileManagerShow() {
        int div;
        final int w = 160;
        if (MenuItemViewFileManager.isSelected()) {
            FileManagerScrollPane.setEnabled(true);
            FileManagerScrollPane.setVisible(true);
            //div = prefs.getInt( FM_DIV, RightFilesSplitPane.getWidth()-w );
            //if ( div > RightFilesSplitPane.getWidth()-w ) {
            div = RightFilesSplitPane.getWidth() - w;
            //}
            RightFilesSplitPane.setDividerLocation(div);
        } else {
            FileManagerScrollPane.setEnabled(false);
            FileManagerScrollPane.setVisible(false);
            RightFilesSplitPane.setDividerLocation(RightFilesSplitPane.getWidth() - RightFilesSplitPane.getDividerSize());
        }
    }

    private void isLogShow() {
        if (MenuItemViewLog.isSelected()) {
            ScrollLog.setVisible(true);
            ScrollLog.setEnabled(true);
            RightSplitPane.setDividerLocation(prefs.getInt(LOG_DIV, RightSplitPane.getHeight() - 200));
        } else {
            ScrollLog.setVisible(false);
            ScrollLog.setEnabled(false);
            RightSplitPane.setDividerLocation(RightSplitPane.getHeight() - RightSplitPane.getDividerSize());
        }
    }
    private void ReScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ReScanActionPerformed
        PortFinder();
    }//GEN-LAST:event_ReScanActionPerformed

    private void SendCommandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SendCommandActionPerformed
        if (CommandEcho.isSelected()) {
            if (Terminal.getCaretOffsetFromLineStart() > 0) {
                TerminalAdd("\r\n");
            }
            TerminalAdd(Command.getSelectedItem().toString());
            TerminalAdd("\r\n");
        }
        SendCommand();
    }//GEN-LAST:event_SendCommandActionPerformed

    private void ContextMenuTerminalPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_ContextMenuTerminalPopupMenuWillBecomeVisible
        try {
            MenuItemTerminalCopy.setEnabled(Terminal.getSelectedText().length() > 0);
        } catch (Exception e) {
            MenuItemTerminalCopy.setEnabled(false);
        }
        int size = Terminal.getFont().getSize();
        String inc, dec;
        if (size < TERMINAL_FONT_SIZE_MAX) {
            inc = "字体从 " + Integer.toString(size) + "更改到" + Integer.toString(size + 1);
        } else {
            inc = "字体大小" + Float.toString(TERMINAL_FONT_SIZE_MIN);
        }
        MenuItemTerminalFontInc.setText(inc);
        if (size > TERMINAL_FONT_SIZE_MIN) {
            dec = "字体大小" + Integer.toString(size) + "更改到" + Integer.toString(size - 1);
        } else {
            dec = "字体大小" + Float.toString(TERMINAL_FONT_SIZE_MAX);
        }
        MenuItemTerminalFontDec.setText(dec);
    }//GEN-LAST:event_ContextMenuTerminalPopupMenuWillBecomeVisible

    private void MenuItemTerminalCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalCopyActionPerformed
        Terminal.copy();
    }//GEN-LAST:event_MenuItemTerminalCopyActionPerformed

    private void MenuItemTerminalClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalClearActionPerformed
        Terminal.setText("");
    }//GEN-LAST:event_MenuItemTerminalClearActionPerformed

    private void MenuItemViewLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewLogActionPerformed
        isLogShow();
        prefs.putBoolean(SHOW_LOG, MenuItemViewLog.isSelected());
    }//GEN-LAST:event_MenuItemViewLogActionPerformed

    private void MenuItemFileSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileSaveActionPerformed
        SaveFile();
        if (FileAutoSaveESP.isSelected() && !FileSaveESP.isSelected()) {
            FileSaveESP.doClick();
        }
    }//GEN-LAST:event_MenuItemFileSaveActionPerformed
    boolean isFileNew() {
        try {
            if (FilesTabbedPane.getTitleAt(iTab).equals(NewFile)) {
                return true;
            }
        } catch (Exception e) {
            return true;
        }
        return false;
    }

    boolean SaveFile() {
        boolean success = false;
        if (isFileNew()) { // we saving new file
            log("保存新文件...");
            FileCount++;
            String fileExt;
            if (OptionNodeMCU.isSelected()) {
                fileExt = ".lua";
            } else { // MicroPython
                fileExt = ".py";
            }
            iFile.set(iTab, new File("script" + Integer.toString(FileCount) + fileExt));
            chooser.rescanCurrentDirectory();
            chooser.setSelectedFile(iFile.get(iTab));
            int returnVal = chooser.showSaveDialog(null);
            if (returnVal != JFileChooser.APPROVE_OPTION) {
                log("保存中止由用户。");
                UpdateEditorButtons();
                return false;
            }
            SavePath();
            iFile.set(iTab, chooser.getSelectedFile());
            if (iFile.get(iTab).exists()) {
                log("文件 " + iFile.get(iTab).getName() + " 已经存在，等待用户选择");
                int shouldWrite = Dialog("文件" + iFile.get(iTab).getName() + "已存在，覆盖？", JOptionPane.YES_NO_OPTION);
                if (shouldWrite != JOptionPane.YES_OPTION) {
                    UpdateEditorButtons();
                    log("保存已取消的用户，因为文件" + FileName + "已经存在");
                    return false;
                } else {
                    log("文件" + FileName + "将被用户选择覆盖");
                }
            }
        } else { // we saving file, when open
            log("保存已有文件" + iFile.get(iTab).getName());
        }
        try {
            log("尝试保存文件" + iFile.get(iTab).getName() + " ...");
            fos = new FileOutputStream(iFile.get(iTab));
            osw = new OutputStreamWriter(fos, "UTF-8");
            bw = new BufferedWriter(osw);
            bw.write(TextEditor1.get(iTab).getText());
            bw.flush();
            osw.flush();
            fos.flush();
            FileName = iFile.get(iTab).getName();
            log("保存文件" + FileName + ": 成功");
            FilesTabbedPane.setTitleAt(iTab, FileName);
            UpdateEditorButtons();
            success = true;
        } catch (IOException ex) {
            log("保存文件" + iFile.get(iTab).getName() + ": 失败");
            log(ex.toString());
//            log(ex.getStackTrace().toString());
            JOptionPane.showMessageDialog(null, "错误，文件未保存！");
        }
        try {
            if (bw != null) {
                bw.close();
            }
            if (osw != null) {
                osw.close();
            }
            if (fos != null) {
                fos.close();
            }
        } catch (IOException ex) {
            log(ex.toString());
//            log(ex.getStackTrace().toString());
        }
        TextEditor1.get(iTab).discardAllEdits();
        FileChanged.set(iTab, false);
        UpdateEditorButtons();
        return success;
    }
    private void MenuItemFileNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileNewActionPerformed
        FileNew("");
    }//GEN-LAST:event_MenuItemFileNewActionPerformed
    private void FileNew(String s) {
        if (UseExternalEditor.isSelected()) {
            return;
        }
        AddTab(s);
        if (s.isEmpty()) {
            log("新的空文件就绪。");
        } else {
            log("新文件就绪，内容加载：成功。");
        }
    }
    private void MenuItemEditCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditCutActionPerformed
        if (UseExternalEditor.isSelected()) {
            return;
        }
        TextEditor1.get(iTab).cut();
        FileChanged.set(iTab, true);
    }//GEN-LAST:event_MenuItemEditCutActionPerformed

    private void MenuItemEditCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditCopyActionPerformed
        TextEditor1.get(iTab).copy();
    }//GEN-LAST:event_MenuItemEditCopyActionPerformed

    private void MenuItemEditPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditPasteActionPerformed
        if (UseExternalEditor.isSelected()) {
            return;
        }
        TextEditor1.get(iTab).paste();
        FileChanged.set(iTab, true);
    }//GEN-LAST:event_MenuItemEditPasteActionPerformed
// File open
    private void MenuItemFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileOpenActionPerformed
        OpenFile();
    }//GEN-LAST:event_MenuItemFileOpenActionPerformed
    private void SavePath() {
        workDir = chooser.getCurrentDirectory().toString();
        prefs.put(PATH, workDir);
    }

    private void OpenFile() {
        chooser.rescanCurrentDirectory();
        int success = chooser.showOpenDialog(LeftBasePane);
        if (success == JFileChooser.APPROVE_OPTION) {
            SavePath();
            int isOpen = -1;
            for (int i = 0; i < iFile.size(); i++) {
                if (chooser.getSelectedFile().getPath().equals(iFile.get(i).getPath())) {
                    iTab = i;
                    isOpen = i;
                    break;
                }
            }
            if (isOpen >= 0) {
                FilesTabbedPane.setSelectedIndex(iTab);
                UpdateEditorButtons();
                FileName = chooser.getSelectedFile().getName();
                log("文件" + FileName + "已经打开，选择选项卡到文件" + FileName);
                JOptionPane.showMessageDialog(null, "文件" + FileName + "已经打开。您只能使用“重载”");
                return;
            }
            if (!isFileNew() || isChanged()) {
                AddTab("");
            }
            log("尝试打开文件" + chooser.getSelectedFile().getName());
            try {
                iFile.set(iTab, chooser.getSelectedFile());
                FileName = iFile.get(iTab).getName();
                log("文件名: " + iFile.get(iTab).getPath());
                if (iFile.get(iTab).length() > 1024 * 1024) { // 1M
                    JOptionPane.showMessageDialog(null, "文件" + FileName + "太大");
                    log("文件太大，大小: " + Long.toString(iFile.get(iTab).length() / 1024 / 1024) + " Mb, 文件: " + iFile.get(iTab).getPath());
                    UpdateEditorButtons();
                    return;
                }
                FilesTabbedPane.setTitleAt(iTab, iFile.get(iTab).getName());
            } catch (HeadlessException ex) {
                JOptionPane.showMessageDialog(null, "错误，文件未打开");
                log(ex.toString());
                log("打开: 失败.");
//                log(ex.getStackTrace().toString());
            }
            if (LoadFile()) {
                log("打开 \"" + FileName + "\": 成功.");
            }
        }
        UpdateEditorButtons();
    }

    private boolean LoadFile() {
        boolean success;
        if (isFileNew()) {
            UpdateEditorButtons();
            log("内部错误101:FileTab是新文件。");
            return false;
        }
        FileName = "";
        try {
            FileName = iFile.get(iTab).getName();
            log("尝试重载文件 " + FileName);
        } catch (Exception e) {
            log("内部错误102:没有当前文件描述符。");
            return false;
        }
        try {
            fis = new FileInputStream(iFile.get(iTab));
            isr = new InputStreamReader(fis, "UTF-8");
            br = new BufferedReader(isr);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append('\n');
            }
            TextEditor1.get(iTab).setText(sb.toString());
            success = true;
        } catch (IOException ex) {
            log(ex.toString());
            log("加载 " + FileName + ": 失败.");
            UpdateEditorButtons();
            JOptionPane.showMessageDialog(null, "错误，文件没有重载！");
            return false;
        }
        try {
            if (br != null) {
                br.close();
            }
            if (isr != null) {
                isr.close();
            }
            if (fis != null) {
                fis.close();
            }
        } catch (IOException ex) {
            log(ex.toString());
            log("内部错误103:不能关闭流。");
        }
        if (success) {
            TextEditor1.get(iTab).setCaretPosition(0);
            FileChanged.set(iTab, false);
            TextEditor1.get(iTab).discardAllEdits();
            UpdateEditorButtons();
            FileLabelUpdate();
            if (UseExternalEditor.isSelected()) {
                TextEditor1.get(iTab).setEditable(false);
            }
            log("加载 " + FileName + ": 成功");
        }
        return success;
    }

    private boolean PrefsFlush() {
        boolean success = false;
        try {
            prefs.flush();
            success = true;
        } catch (BackingStoreException e) {
            log("错误:无法保存某些设置。");
            log(e.toString());
        }
        return success;
    }
    private void MenuItemEditorCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorCutActionPerformed
        MenuItemEditCut.doClick();
    }//GEN-LAST:event_MenuItemEditorCutActionPerformed

    private void MenuItemEditorCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorCopyActionPerformed
        MenuItemEditCopy.doClick();
    }//GEN-LAST:event_MenuItemEditorCopyActionPerformed

    private void MenuItemEditorPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorPasteActionPerformed
        MenuItemEditPaste.doClick();
    }//GEN-LAST:event_MenuItemEditorPasteActionPerformed

    private void MenuItemLogClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLogClearActionPerformed
        Log.setText("");
    }//GEN-LAST:event_MenuItemLogClearActionPerformed
    private void CheckSelected() {
        if (TextEditor1.get(iTab).getSelectedText() == null) {
            MenuItemEditorCut.setEnabled(false);
            MenuItemEditCut.setEnabled(false);
            MenuItemEditorCopy.setEnabled(false);
            MenuItemEditCopy.setEnabled(false);
            ButtonCut.setEnabled(false);
            ButtonCopy.setEnabled(false);
            MenuItemEditSendSelected.setEnabled(false);
            MenuItemEditorSendSelected.setEnabled(false);
            ButtonSendSelected.setEnabled(false);
        } else {
            MenuItemEditorCut.setEnabled(true);
            MenuItemEditCut.setEnabled(true);
            MenuItemEditorCopy.setEnabled(true);
            MenuItemEditCopy.setEnabled(true);
            ButtonCut.setEnabled(true);
            ButtonCopy.setEnabled(true);
            MenuItemEditSendSelected.setEnabled(pOpen);
            MenuItemEditorSendSelected.setEnabled(pOpen);
            ButtonSendSelected.setEnabled(pOpen);
        }
        try {
            if (Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null) == null) { // clipboard empty
                MenuItemEditorPaste.setEnabled(false);
                MenuItemEditPaste.setEnabled(false);
                ButtonPaste.setEnabled(false);
            } else {
                MenuItemEditorPaste.setEnabled(true);
                MenuItemEditPaste.setEnabled(true);
                ButtonPaste.setEnabled(true);
            }
        } catch (HeadlessException e) {
        }
    }

    private void UpdateEditorButtons() {
        iTab = FilesTabbedPane.getSelectedIndex();
        // isChanged
        if (isChanged() && !UseExternalEditor.isSelected()) {
            if (isFileNew()) {
                MenuItemFileSave.setEnabled(true);
                ButtonFileSave.setEnabled(true);
                MenuItemFileReload.setEnabled(false);
                ButtonFileReload.setEnabled(false);
            } else {
                MenuItemFileSave.setEnabled(true);
                ButtonFileSave.setEnabled(true);
                MenuItemFileReload.setEnabled(true);
                ButtonFileReload.setEnabled(true);
            }
        } else if (isFileNew()) {
            MenuItemFileSave.setEnabled(true);
            ButtonFileSave.setEnabled(true);
            MenuItemFileReload.setEnabled(false);
            ButtonFileReload.setEnabled(false);
        } else {
            MenuItemFileSave.setEnabled(false);
            ButtonFileSave.setEnabled(false);
            MenuItemFileReload.setEnabled(true);
            ButtonFileReload.setEnabled(true);
        }
        if (isFileNew() && (FilesTabbedPane.getTabCount() == 1)) {
            MenuItemFileClose.setEnabled(false);
            ButtonFileClose.setEnabled(false);
        } else {
            MenuItemFileClose.setEnabled(true);
            ButtonFileClose.setEnabled(true);
        }
        // CanUndo
        try {
            if (TextEditor1.isEmpty()) {
                return;
            }
        } catch (Exception e) {
            return;
        }
        if (TextEditor1.get(iTab).canUndo()) {
            MenuItemEditUndo.setEnabled(true);
            MenuItemEditorUndo.setEnabled(true);
            ButtonUndo.setEnabled(true);
        } else {
            MenuItemEditUndo.setEnabled(false);
            MenuItemEditorUndo.setEnabled(false);
            ButtonUndo.setEnabled(false);
        }
        // CanRedo
        if (TextEditor1.get(iTab).canRedo()) {
            MenuItemEditRedo.setEnabled(true);
            MenuItemEditorRedo.setEnabled(true);
            ButtonRedo.setEnabled(true);
        } else {
            MenuItemEditRedo.setEnabled(false);
            MenuItemEditorRedo.setEnabled(false);
            ButtonRedo.setEnabled(false);
        }
        CheckSelected();
        if (UseExternalEditor.isSelected()) {
            MenuItemFileReload.setEnabled(true);
            ButtonFileReload.setEnabled(true);

            MenuItemFileSave.setEnabled(false);
            ButtonFileSave.setEnabled(false);
            MenuItemEditUndo.setEnabled(false);
            MenuItemEditorUndo.setEnabled(false);
            ButtonUndo.setEnabled(false);
            MenuItemEditRedo.setEnabled(false);
            MenuItemEditorRedo.setEnabled(false);
            ButtonRedo.setEnabled(false);
            MenuItemEditorCut.setEnabled(false);
            MenuItemEditCut.setEnabled(false);
            ButtonCut.setEnabled(false);
            MenuItemEditorPaste.setEnabled(false);
            MenuItemEditPaste.setEnabled(false);
            ButtonPaste.setEnabled(false);
            MenuItemFileNew.setEnabled(false);
            ButtonFileNew.setEnabled(false);
            MenuItemFileSaveAs.setEnabled(false);
        } else {
            MenuItemFileNew.setEnabled(true);
            ButtonFileNew.setEnabled(true);
            MenuItemFileSaveAs.setEnabled(true);
        }
    }
    private void formFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_formFocusGained
        UpdateEditorButtons();
        UpdateButtons();
    }//GEN-LAST:event_formFocusGained

    private void MenuItemFileReloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileReloadActionPerformed
        ReloadFile();
    }//GEN-LAST:event_MenuItemFileReloadActionPerformed

    private void MenuItemFileCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileCloseActionPerformed
        CloseFile();
    }//GEN-LAST:event_MenuItemFileCloseActionPerformed

    private void MenuItemViewClearTerminalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewClearTerminalActionPerformed
        MenuItemTerminalClear.doClick();
    }//GEN-LAST:event_MenuItemViewClearTerminalActionPerformed

    private void MenuItemViewClearLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewClearLogActionPerformed
        MenuItemLogClear.doClick();
    }//GEN-LAST:event_MenuItemViewClearLogActionPerformed

    private void AlwaysOnTopItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_AlwaysOnTopItemStateChanged
        this.setAlwaysOnTop(AlwaysOnTop.isSelected());
    }//GEN-LAST:event_AlwaysOnTopItemStateChanged

    private void MenuItemEditUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditUndoActionPerformed
        if (TextEditor1.get(iTab).canUndo()) {
            TextEditor1.get(iTab).undoLastAction();
        }
    }//GEN-LAST:event_MenuItemEditUndoActionPerformed

    private void MenuItemEditRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditRedoActionPerformed
        if (TextEditor1.get(iTab).canRedo()) {
            TextEditor1.get(iTab).redoLastAction();
        }
    }//GEN-LAST:event_MenuItemEditRedoActionPerformed

    private void MenuItemEditorRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorRedoActionPerformed
        MenuItemEditRedo.doClick();
    }//GEN-LAST:event_MenuItemEditorRedoActionPerformed

    private void MenuItemEditorUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorUndoActionPerformed
        MenuItemEditUndo.doClick();
    }//GEN-LAST:event_MenuItemEditorUndoActionPerformed
    private void NodeListFiles() {
        if (portJustOpen) {
            log("错误:未与MCU建立通信。");
            return;
        }
        //String cmd = "print(\"~~~File \"..\"list START~~~\") for k,v in pairs(file.list()) do l = string.format(\"%-15s\",k) print(l..\" - \"..v..\" bytes\") end l=nil k=nil v=nil print(\"~~~File \"..\"list END~~~\")";
        String cmd = "_dir=function()\n"
                + "     local k,v,l\n"
                + "     print(\"~~~File \"..\"list START~~~\")\n"
                + "     for k,v in pairs(file.list()) do \n"
                + "          l = string.format(\"%-15s\",k) \n"
                + "          print(l..\" : \"..v..\" bytes\") \n"
                + "     end \n"
                + "     print(\"~~~File \"..\"list END~~~\")\n"
                + "end\n"
                + "_dir()\n"
                + "_dir=nil";
        try {
            serialPort.removeEventListener();
        } catch (SerialPortException e) {
            log(e.toString());
        }
        try {
            serialPort.addEventListener(new PortNodeFilesReader(), portMask);
            log("添加EventListener:成功。");
        } catch (SerialPortException e) {
            log("添加EventListener错误。取消了。");
            return;
        }
        ClearNodeFileManager();
        rx_data = "";
        rcvBuf = "";
        sendBuf = cmdPrep(cmd);
        log("文件管理:开始…");
        SendLock();
        int delay = 10;
        j0();
        taskPerformer = (ActionEvent evt) -> {
            if (j < sendBuf.size()) {
                LocalEcho = false;
                send(addCR(sendBuf.get(j)), false);
                sendPending = false;
            }
        };
        timer = new Timer(delay, taskPerformer);
        timer.setRepeats(false);
        timer.setInitialDelay(delay);
        WatchDog();
        timer.start();
    }

    private void ClearNodeFileManager() {
        if (!MenuItemViewFileManager.isSelected()) {
            return;
        }
        NodeFileManagerPane.removeAll();
        NodeFileManagerPane.add(FileFormat);
        NodeFileManagerPane.add(FileSystemInfo);
        NodeFileManagerPane.add(FileListReload);
        NodeFileManagerPane.add(FileRenamePanel);
        FileRenamePanel.setVisible(false);
        FileRenamePanel.setEnabled(false);
        NodeFileManagerPane.repaint();
        FileAsButton = new ArrayList<>();
    }

    private class PortNodeFilesReader implements SerialPortEventListener {

        @Override
        public void serialEvent(SerialPortEvent event) {
            String data;
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                try {
                    data = serialPort.readString(event.getEventValue());
                    rcvBuf = rcvBuf + data;
                    rx_data = rx_data + data;
                } catch (SerialPortException e) {
                    log(e.toString());
                }
                if (rcvBuf.contains("> ")) {
                    try {
                        timeout.restart();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    rcvBuf = "";
                    if (j < sendBuf.size() - 1) {
                        if (timer.isRunning() || sendPending) {
                            //
                        } else {
                            inc_j();
                            sendPending = true;
                            timer.start();
                        }
                    } else { // send done
                        try {
                            timer.stop();
                        } catch (Exception e) {
                        }
                    }
                }
                try {
                    if (rx_data.contains("~~~File list END~~~")) {
                        try {
                            timeout.stop();
                        } catch (Exception e) {
                            log(e.toString());
                        }
                        ProgressBar.setValue(100);
                        log("文件管理:文件列表找到!解析…");
                        try {
                            // parsing answer
                            int start = rx_data.indexOf("~~~File list START~~~");
                            rx_data = rx_data.substring(start + 23, rx_data.indexOf("~~~File list END~~~"));
                            //log(rx_data.replaceAll("\r?\n", "<CR+LF>\r\n"));
                            s = rx_data.split("\r?\n");
                            Arrays.sort(s);
//                            TerminalAdd("\r\n" + rx_data + "\r\n> ");
                            int usedSpace = 0;
                            TerminalAdd("\r\n----------------------------");
                            for (String subs : s) {
                                TerminalAdd("\r\n" + subs);
                                String[] parts = subs.split(":");
                                if (parts[0].trim().length() > 0) {
                                    int size = Integer.parseInt(parts[1].trim().split(" ")[0]);
                                    AddNodeFileButton(parts[0].trim(), size);
                                    usedSpace += size;
                                    log("文件管理：发现文件 " + parts[0].trim());
                                }
                            }
                            if (FileAsButton.isEmpty()) {
                                TerminalAdd("没找到文件");
                                TerminalAdd("\r\n----------------------------\r\n> ");
                            } else {
                                TerminalAdd("\r\n----------------------------");
                                TerminalAdd("\r\n合计 文件   : " + Integer.toString(s.length));
                                TerminalAdd("\r\n合计 大小      : " + Integer.toString(usedSpace) + " 字节\r\n");
                            }
                            NodeFileManagerPane.invalidate();
                            NodeFileManagerPane.doLayout();
                            NodeFileManagerPane.repaint();
                            NodeFileManagerPane.requestFocusInWindow();
                            log("文件列表解析完成，找到 " + FileAsButton.size() + " 文件");
                        } catch (NumberFormatException e) {
                            log(e.toString());
                        }
                        try {
                            serialPort.removeEventListener();
                        } catch (SerialPortException e) {
                        }
                        serialPort.addEventListener(new PortReader(), portMask);
                        SendUnLock();
                        NodeFileSystemInfo();
                    }
                } catch (SerialPortException ex) {
                    log(ex.toString());
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("接收到未知的串口错误。");
            }
        }
    }

    private void FileDownload(String param) {
        if (portJustOpen) {
            log("下载器:与MCU通信尚未建立。");
            return;
        }
        // param  init.luaSize:123
        DownloadedFileName = param.split("Size:")[0];
        int size = Integer.parseInt(param.split("Size:")[1]);
        packets = size / 1024;
        if (size % 1024 > 0) {
            packets++;
        }
        sendBuf = new ArrayList<>();
        rcvPackets = new ArrayList<>();
        PacketsData = new ArrayList<>();
        PacketsSize = new ArrayList<>();
        PacketsNum = new ArrayList<>();
        rcvFile = "";
        PacketsByte = new byte[0];
        rx_byte = new byte[0];
        PacketsCRC = new ArrayList<>();
        String cmd = "_dl=function() "
                + "  file.open(\"" + DownloadedFileName + "\", \"r\")\n"
                + "  local buf "
                + "  local i=0 "
                + "  local checksum\n"
                + "  repeat "
                + "     buf = file.read(1024) "
                + "     if buf ~= nil then "
                + "          i = i + 1 "
                + "          checksum = 0 "
                + "          for j=1, string.len(buf) do\n"
                + "               checksum = checksum + (buf:byte(j)*20)%19 "
                + "          end "
                + "          buf='~~~'..'DATA-START~~~'..buf..'~~~'..'DATA-LENGTH~~~'..string.len(buf)..'~~~'..'DATA-N~~~'..i..'~~~'..'DATA-CRC~~~'..checksum..'~~~'..'DATA-END~~~'\n"
                + "          uart.write(0,buf) "
                + "     end "
                + "     tmr.wdclr() "
                + "  until(buf == nil) "
                + "  file.close()\n"
                + "  buf='~~~'..'DATA-TOTAL-START~~~'..i..'~~~'..'DATA-TOTAL-END~~~'\n"
                + "  uart.write(0,buf) "
                + "end "
                + "_dl() "
                + "_dl=nil\n";
        s = cmd.split("\r?\n");
        sendBuf.addAll(Arrays.asList(s));
        log("下载器: 开始...");
        startTime = System.currentTimeMillis();
        SendLock();
        rx_data = "";
        rcvBuf = "";
        rx_byte = new byte[0];
        try {
            serialPort.removeEventListener();
        } catch (SerialPortException e) {
            log(e.toString());
        }
        try {
            serialPort.addEventListener(new PortFileDownloader(), portMask);
            log("下载器: 添加EventListener:成功。");
        } catch (SerialPortException e) {
            log("下载器: 添加EventListener错误。取消了。");
            return;
        }
        int delay = 10;
        j0();
        taskPerformer = (ActionEvent evt) -> {
            if (j < sendBuf.size()) {
                send(addCR(sendBuf.get(j)), false);
                sendPending = false;
            }
        };
        timer = new Timer(delay, taskPerformer);
        timer.setRepeats(false);
        log("下载器: 开始");
        TerminalAdd("\r\n下载文件 \"" + DownloadedFileName + "\"...");
        timer.setInitialDelay(delay);
        WatchDog();
        timer.start();
    }

    private void FileDownloadFinisher(boolean success) {
        try {
            serialPort.removeEventListener();
        } catch (SerialPortException e) {
            log(e.toString());
        }
        try {
            serialPort.addEventListener(new PortReader(), portMask);
        } catch (SerialPortException e) {
            log("下载器: 不能添加旧的EventListener。");
        }
        //SendUnLock();
        StopSend();
        if (success) {
            TerminalAdd("成功。\r\n");
            if (DownloadCommand.startsWith("EDIT")) {
                FileNew(rcvFile);
            } else if (DownloadCommand.startsWith("DOWNLOAD")) {
                SaveDownloadedFile();
            } else {
                // nothing, reserved
            }
        } else {
            TerminalAdd("失败.\r\n");
        }
    }

    private byte[] concatArray(byte[] a, byte[] b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        byte[] r = new byte[a.length + b.length];
        System.arraycopy(a, 0, r, 0, a.length);
        System.arraycopy(b, 0, r, a.length, b.length);
        return r;
    }

    private class PortFileDownloader implements SerialPortEventListener {

        @Override
        public void serialEvent(SerialPortEvent event) {
            String data;
            byte[] b;
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                try {
                    b = serialPort.readBytes();
                    rx_byte = concatArray(rx_byte, b);
                    data = new String(b);
                    rcvBuf = rcvBuf + data;
                    rx_data = rx_data + data;
                    //TerminalAdd(data);
                } catch (SerialPortException e) {
                    log(e.toString());
                }
                if (rcvBuf.contains("> ")) {
                    try {
                        timeout.restart();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    rcvBuf = "";
                    if (j < sendBuf.size() - 1) {
                        if (timer.isRunning() || sendPending) {
                            //
                        } else {
                            inc_j();
                            sendPending = true;
                            timer.start();
                        }
                    } else { // send done
                        try {
                            timer.stop();
                        } catch (Exception e) {
                        }
                    }
                }
                /*
                String l = data.replace("\r", "<CR>");
                l = l.replace("\n", "<LF>");
                l = l.replace("`", "<OK>");
                log("recv:" + l);
                 */
                if ((rx_data.lastIndexOf("~~~DATA-END") >= 0) && (rx_data.lastIndexOf("~~~DATA-START") >= 0)) {
                    // we got full packet
                    rcvPackets.add(rx_data.split("~~~DATA-END")[0]); // store RAW data
                    rx_data = rx_data.substring(rx_data.indexOf("~~~DATA-END") + 11); // and remove it from buf
                    if (packets > 0) { // exclude div by zero
                        ProgressBar.setValue(rcvPackets.size() * 100 / packets);
                    }
                    //  ~~~DATA-START~~~buf~~~DATA-LENGTH~~~string.len(buf)~~~DATA-N~~~i~~~DATA-CRC~~~CheckSum~~~DATA-END
                    //0        1                  2                               3            4                     5
                    // split packet & check crc
                    int i = rcvPackets.size() - 1;
                    String[] part = rcvPackets.get(i).split("~~~DATA-CRC~~~");
                    PacketsCRC.add(Integer.parseInt(part[1]));
                    String left = part[0];
                    part = left.split("~~~DATA-N~~~");
                    PacketsNum.add(Integer.parseInt(part[1]));
                    left = part[0];
                    part = left.split("~~~DATA-LENGTH~~~");
                    PacketsSize.add(Integer.parseInt(part[1]));
                    left = part[0];
                    part = left.split("~~~DATA-START~~~");
                    PacketsData.add(part[1]);
                    int startData = FindPacketID(i + 1);
                    byte[] x;
                    if ((startData > 0) && (rx_byte.length >= (startData + PacketsSize.get(i)))) {
                        x = copyPartArray(rx_byte, startData, PacketsSize.get(i));
                        //log("下载器：data from packet #" + Integer.toString(i+1) + " found in raw data");
                    } else {
                        x = new byte[0];
                        //log("下载器：data packet #" + Integer.toString(i+1) + " not found in raw data.");
                        //log("raw date length " + rx_byte.length +
                        //    "\r\nstartData " + Integer.toString(startData) );
                    }
                    //rx_byte = new byte[0];
                    if (PacketsCRC.get(i) == CRC(x)) {
                        try {
                            timeout.restart();
                        } catch (Exception e) {
                            log(e.toString());
                        }
                        rcvFile = rcvFile + PacketsData.get(i);
                        PacketsByte = concatArray(PacketsByte, x);
                        log("下载器: 收到包: " + Integer.toString(PacketsNum.get(i)) + "/" + Integer.toString(packets)
                                + ", 大小:" + Integer.toString(PacketsSize.get(i))
                                + ", CRC 校验: 成功");
                    } else {
                        try {
                            timeout.stop();
                        } catch (Exception e) {
                            log(e.toString());
                        }
                        log("下载器：接收到包: " + Integer.toString(PacketsNum.get(i)) + "/" + Integer.toString(packets)
                                + ", 预期大小:" + Integer.toString(PacketsSize.get(i))
                                + ", 收到大小:" + Integer.toString(PacketsByte.length)
                                + "\r\n, 预期CRC  :" + Integer.toString(PacketsCRC.get(i))
                                + "  收到CRC  :" + Integer.toString(CRC(x)));
                        log("下载器：失败");
                        PacketsCRC.clear();
                        PacketsNum.clear();
                        PacketsSize.clear();
                        PacketsData.clear();
                        rcvPackets.clear();
                        rcvFile = "";
                        PacketsByte = new byte[0];
                        FileDownloadFinisher(false);
                    }
                } else if ((rx_data.lastIndexOf("~~~DATA-TOTAL-END~~~") >= 0) && (PacketsNum.size() == packets)) {
                    try {
                        timeout.stop();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    ProgressBar.setValue(100);
                    log("下载器：得到最终的层序。文件下载:成功");
                    //log(rx_data);
                    FileDownloadFinisher(true);
                } else {
                    //log("rxbyte - " + Integer.toString( rx_byte.length ));
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("下载器：接收到未知的串行端口错误。");
                FileDownloadFinisher(false);
            }
        }
    }

    private byte[] copyPartArray(byte[] a, int start, int len) {
        if (a == null) {
            return null;
        }
        if (start > a.length) {
            return null;
        }
        byte[] r = new byte[len];
        try {
            System.arraycopy(a, start, r, 0, len);
        } catch (Exception e) {
            log(e.toString());
            log("复制部分数组异常");
            log("大小 a=" + Integer.toString(a.length));
            log("开始 =" + Integer.toString(start));
            log("长度   =" + Integer.toString(len));
        }
        return r;
    }

    private int FindPacketID(int nPacket) {
        int i, j, n, ret = -1;
        boolean success;
        String s = "~~~DATA-START~~~";
        i = 0;
        n = 0;
        while (i < rx_byte.length - s.length()) {
            success = true;
            for (j = 0; j < s.length(); j++) {
                if (!(rx_byte[i + j] == s.charAt(j))) {
                    success = false;
                    break;
                }
            }
            if (success) {
                n++;
                //log("下载器：n =" + Integer.toString(n));
                //log("下载器：nPacket =" + Integer.toString(nPacket));
            }
            if (success && (n == nPacket)) {
                ret = i + s.length();
                break;
            } else {
            }
            i++;
        }
        //log("下载器：FindPacketID=" + Integer.toString(ret));
        return ret;
    }

    private int CRC(byte[] s) {
        int cs = 0;
        int x;
        try {
            for (int i = 0; i < s.length; i++) {
                x = s[i] & 0xFF;
                //log( Integer.toHexString(x) );
                cs = cs + (x * 20) % 19;
            }
            //log("\r\nCRC size= " + Integer.toString(s.length)+ ", CRC="+Integer.toString(cs));
        } catch (Exception e) {
            log(e.toString());
            log(Arrays.toString(e.getStackTrace()));
            log("size=" + Integer.toString(s.length));
        }
        return cs;
    }

    private void HexDump(String FileName) {
        String cmd = "_dump=function()\n"
                + "  local buf\n"
                + "  local j=0\n"
                + "  if file.open(\"" + FileName + "\", \"r\") then\n"
                + "  print('--HexDump start')\n"
                + "  repeat\n"
                + "     buf=file.read(1024)\n"
                + "     if buf~=nil then\n"
                + "     local n \n"
                + "     if #buf==1024 then\n"
                + "        n=(#buf/16)*16\n"
                + "     else\n"
                + "        n=(#buf/16+1)*16\n"
                + "     end\n"
                + "     for i=1,n do\n"
                + "         j=j+1\n"
                + "         if (i-1)%16==0 then\n"
                + "            uart.write(0,string.format('%08X  ',j-1)) \n"
                + "         end\n"
                + "         uart.write(0,i>#buf and'   'or string.format('%02X ',buf:byte(i)))\n"
                + "         if i%8==0 then uart.write(0,' ')end\n"
                + "         if i%16==0 then uart.write(0,buf:sub(i-16+1, i):gsub('%c','.'),'\\n')end\n"
                + "         if i%128==0 then tmr.wdclr()end\n"
                + "     end\n"
                + "     end\n"
                + "  until(buf==nil)\n"
                + "  file.close()\n"
                + "  print(\"\\r--HexDump done.\")\n"
                + "  else\n"
                + "  print(\"\\r--HexDump error: can't open file\")\n"
                + "  end\n"
                + "end\n"
                + "_dump()\n"
                + "_dump=nil\n";
        LocalEcho = false;
        SendToESP(cmdPrep(cmd));
    }

    private ArrayList<String> cmdPrep(String cmd) {
        String[] str = cmd.split("\n");
        ArrayList<String> s256 = new ArrayList<>();
        int i = 0;
        s256.add("");
        for (String subs : str) {
            if ((s256.get(i).length() + subs.trim().length()) <= 250) {
                s256.set(i, s256.get(i) + " " + subs.trim());
            } else {
                s256.set(i, s256.get(i) + "\r");
                s256.add(subs);
                i++;
            }
        }
        return s256;
    }

    private void UpdateLedCTS() {
        try {
            if (serialPort.isCTS()) {
                PortCTS.setIcon(LED_GREEN);
            } else {
                PortCTS.setIcon(LED_GREY);
            }
        } catch (SerialPortException e) {
            log(e.toString());
        }
    }

    private void TerminalAdd(String s) {
        Document doc = Terminal.getDocument();
        if (doc.getLength() > TerminalMax) {
            try {
                doc.remove(0, 1024);
            } catch (BadLocationException e) {
            }
        }
        try {
            doc.insertString(doc.getLength(), s, null);
        } catch (BadLocationException e) {
            log(e.toString());
        }
        if (AutoScroll.isSelected()) {
            try {
                Terminal.setCaretPosition(doc.getLength());
            } catch (Exception e) {
                log(e.toString());
            }
        }
    }
    private void MenuItemEditorSendSelectedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorSendSelectedActionPerformed
        MenuItemEditSendSelected.doClick();
    }//GEN-LAST:event_MenuItemEditorSendSelectedActionPerformed

    private void MenuItemEditSendSelectedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditSendSelectedActionPerformed
        int l;
        if ((LeftTab.getSelectedIndex() == 0) && (TextTab.getSelectedIndex() == 0)) { // NodeMCU and Scripts
            try {
                l = TextEditor1.get(iTab).getSelectedText().length();
            } catch (Exception e) {
                log("无法发送:没有选择。");
                return;
            }
            if (l > 0) {
                SendToESP(TextEditor1.get(iTab).getSelectedText());
            }
        } else if ((LeftTab.getSelectedIndex() == 0) && (TextTab.getSelectedIndex() == 0)) { // NodeMCU and Snippets
            try {
                l = SnippetText.getSelectedText().length();
            } catch (Exception e) {
                log("无法发送:没有选择。");
                return;
            }
            if (l > 0) {
                SendToESP(SnippetText.getSelectedText());
            }
        }
    }//GEN-LAST:event_MenuItemEditSendSelectedActionPerformed

    private void MenuItemFileRemoveESPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileRemoveESPActionPerformed
        String ft = iFile.get(iTab).getName();
        if (ft.length() == 0) {
            log("ESP文件删除:失败。不能从ESP中删除没有名称的文件。");
            JOptionPane.showMessageDialog(null, "Can't remove file from ESP without name.");
        }
        FileRemoveESP(ft);
    }//GEN-LAST:event_MenuItemFileRemoveESPActionPerformed
    private void FileRemoveESP(String FileName) {
        btnSend("file.remove(\"" + FileName + "\")");
        try {
            Thread.sleep(200L);
        } catch (InterruptedException e) {
        }
        FileListReload.doClick();
    }
    private void MenuItemFileSaveESPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileSaveESPActionPerformed
        if (!FileSaveESP.isSelected()) {
            FileSaveESP.doClick();
        }
    }//GEN-LAST:event_MenuItemFileSaveESPActionPerformed

    private void NodeResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NodeResetActionPerformed
        cmdNodeRestart.doClick();
    }//GEN-LAST:event_NodeResetActionPerformed

    private void MenuItemLogCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLogCloseActionPerformed
        MenuItemViewLog.doClick();
    }//GEN-LAST:event_MenuItemLogCloseActionPerformed

    private void MenuItemTerminalResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalResetActionPerformed
        MenuItemESPReset.doClick();
    }//GEN-LAST:event_MenuItemTerminalResetActionPerformed

    private void DonateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DonateActionPerformed
        goLink(donate_uri);
    }//GEN-LAST:event_DonateActionPerformed

    private void MenuItemHelpAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemHelpAboutActionPerformed
        About.setLocationRelativeTo(null);
        About.setVisible(true);
    }//GEN-LAST:event_MenuItemHelpAboutActionPerformed

    private void AboutFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_AboutFocusLost
        About.dispose();
    }//GEN-LAST:event_AboutFocusLost

    private void HomePageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_HomePageActionPerformed
        goLink(homepage_uri);
    }//GEN-LAST:event_HomePageActionPerformed

    private void PortItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_PortItemStateChanged

    }//GEN-LAST:event_PortItemStateChanged
    private void LoadSnippets() {
        String suffix;
        if (OptionNodeMCU.isSelected()) {
            suffix = "";
            SnippetText.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LUA);
        } else {
            suffix = "_mpy";
            SnippetText.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
        }
        log("片段: 加载...");
        for (int i = 0; i <= 15; i++) {
            String n = Integer.toString(i).trim();
            if (prefs.get("Snippet" + n + suffix + "name", null) == null) {
                prefs.put("Snippet" + n + suffix + "name", "Snippet" + n);
                prefs.put("Snippet" + n + suffix, "");
                PrefsFlush();
            }
            JButton snippetButton = snippetButtons.get(i);
            String newText = prefs.get("Snippet" + n + suffix + "name", "Snippet" + n);
            snippetButton.setText(newText);
            Snippets[i] = prefs.get("Snippet" + n + suffix, "");
        }
        if (OptionMicroPython.isSelected())
        {
            if (Snippets[0].isEmpty())
            {
                ButtonSnippet0.setText("GPIO2 1");
                prefs.put("Snippet0" + suffix + "name", "Set GPIO2 high");
                Snippets[0] = "from machine import Pin\r\n"
                        + "pin = Pin(2, Pin.OUT)\r\n"
                        + "pin.value(1)";
            }
            if (Snippets[1].isEmpty()) {
                ButtonSnippet1.setText("GPIO2 0");
                prefs.put("Snippet1" + suffix + "name", "Set GPIO2 low");
                Snippets[1] = "from machine import Pin\r\n"
                        + "pin = Pin(2, Pin.OUT)\r\n"
                        + "pin.value(0)";
            }
        }
        SetSnippetEditButtonsTooltip();
        log("片段加载:成功。");
    }

    private void SnippetEdit(int n) {
        if (SnippetText.canUndo() || SnippetText.canRedo()) {
            this.setAlwaysOnTop(false);
            int returnVal = JOptionPane.showConfirmDialog(null, "放弃任何更改并加载代码片段" + Integer.toString(n), "注意", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            this.setAlwaysOnTop(AlwaysOnTop.isSelected());
            if (returnVal != JOptionPane.YES_OPTION) {
                return;
            }
        }
        SnippetText.setEnabled(true);
        iSnippets = n;
        SnippetName.setEnabled(true);
        SnippetSave.setEnabled(true);
        SnippetRun.setEnabled(true);
        SnippetCancelEdit.setEnabled(true);
        SnippetText.setEnabled(true);
        SnippetScrollPane.setEnabled(true);
        SnippetText.setEditable(true);
        SnippetText.setText(Snippets[iSnippets]);
        //SnippetText.setBackground(themeTextBackground);
        SnippetText.discardAllEdits();
        String suffix;
        if (OptionNodeMCU.isSelected()) {
            suffix = "";
        } else {
            suffix = "_mpy";
        }
        String snippetName = prefs.get("Snippet" + n + suffix + "name", "Snippet" + n);
        log("片段名字设置为:" + snippetName);
        SnippetName.setText(snippetName);
    }
    private void ButtonSnippet0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet0ActionPerformed
        DoSnippet(0);
    }//GEN-LAST:event_ButtonSnippet0ActionPerformed

    private void ButtonSnippet1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet1ActionPerformed
        DoSnippet(1);
    }//GEN-LAST:event_ButtonSnippet1ActionPerformed

    private void ButtonSnippet2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet2ActionPerformed
        DoSnippet(2);
    }//GEN-LAST:event_ButtonSnippet2ActionPerformed

    private void ButtonSnippet3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet3ActionPerformed
        DoSnippet(3);
    }//GEN-LAST:event_ButtonSnippet3ActionPerformed

    private void ButtonSnippet4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet4ActionPerformed
        DoSnippet(4);
    }//GEN-LAST:event_ButtonSnippet4ActionPerformed

    private void ButtonSnippet5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet5ActionPerformed
        DoSnippet(5);
    }//GEN-LAST:event_ButtonSnippet5ActionPerformed

    private void ButtonSnippet6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet6ActionPerformed
        DoSnippet(6);
    }//GEN-LAST:event_ButtonSnippet6ActionPerformed

    private void ButtonSnippet7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet7ActionPerformed
        DoSnippet(7);
    }//GEN-LAST:event_ButtonSnippet7ActionPerformed

    private void ButtonSnippet8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet8ActionPerformed
        DoSnippet(8);
    }//GEN-LAST:event_ButtonSnippet8ActionPerformed

    private void ButtonSnippet9ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet9ActionPerformed
        DoSnippet(9);
    }//GEN-LAST:event_ButtonSnippet9ActionPerformed

    private void ButtonSnippet10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet10ActionPerformed
        DoSnippet(10);
    }//GEN-LAST:event_ButtonSnippet10ActionPerformed

    private void ButtonSnippet11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet11ActionPerformed
        DoSnippet(11);
    }//GEN-LAST:event_ButtonSnippet11ActionPerformed

    private void ButtonSnippet12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet12ActionPerformed
        DoSnippet(12);
    }//GEN-LAST:event_ButtonSnippet12ActionPerformed

    private void ButtonSnippet13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet13ActionPerformed
        DoSnippet(13);
    }//GEN-LAST:event_ButtonSnippet13ActionPerformed

    private void ButtonSnippet14ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet14ActionPerformed
        DoSnippet(14);
    }//GEN-LAST:event_ButtonSnippet14ActionPerformed

    private void ButtonSnippet15ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSnippet15ActionPerformed
        DoSnippet(15);
    }//GEN-LAST:event_ButtonSnippet15ActionPerformed

    private void MenuItemEditSendLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditSendLineActionPerformed
        int nLine;
        if ((LeftTab.getSelectedIndex() == 0) && (TextTab.getSelectedIndex() == 0)) { // NodeMCU and Scripts
            nLine = TextEditor1.get(iTab).getCaretLineNumber();
            String cmd = TextEditor1.get(iTab).getText().split("\r?\n")[nLine];
            btnSend(cmd);
        } else if ((LeftTab.getSelectedIndex() == 0) && (TextTab.getSelectedIndex() == 2)) { // NodeMCU and Snippets
            nLine = SnippetText.getCaretLineNumber();
            String cmd = SnippetText.getText().split("\r?\n")[nLine];
            btnSend(cmd);
        }
    }//GEN-LAST:event_MenuItemEditSendLineActionPerformed

    private void MenuItemFileSendESPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileSendESPActionPerformed
        FileSendESP.doClick();
    }//GEN-LAST:event_MenuItemFileSendESPActionPerformed

    private void MenuItemEditorSendLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorSendLineActionPerformed
        MenuItemEditSendLine.doClick();
    }//GEN-LAST:event_MenuItemEditorSendLineActionPerformed

    private void MenuFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuFileActionPerformed

    }//GEN-LAST:event_MenuFileActionPerformed

    private void MenuItemFileDoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileDoActionPerformed
        FileDo.doClick();
    }//GEN-LAST:event_MenuItemFileDoActionPerformed

    private void MenuItemTerminalFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalFontDecActionPerformed
        MenuItemViewTermFontDec.doClick();
    }//GEN-LAST:event_MenuItemTerminalFontDecActionPerformed

    private void MenuItemTerminalFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalFontIncActionPerformed
        MenuItemViewTermFontInc.doClick();
    }//GEN-LAST:event_MenuItemTerminalFontIncActionPerformed

    private void MenuItemViewTermFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewTermFontIncActionPerformed
        int size = Terminal.getFont().getSize();
        if (size < TERMINAL_FONT_SIZE_MAX) {
            Terminal.setFont(Terminal.getFont().deriveFont(Terminal.getFont().getSize() + 1f));
        } else {
            Terminal.setFont(Terminal.getFont().deriveFont(TERMINAL_FONT_SIZE_MAX));
        }
        prefs.putFloat(TERMINAL_FONT_SIZE, Terminal.getFont().getSize());
        PrefsFlush();
    }//GEN-LAST:event_MenuItemViewTermFontIncActionPerformed

    private void MenuItemViewTermFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewTermFontDecActionPerformed
        int size = Terminal.getFont().getSize();
        if (size > TERMINAL_FONT_SIZE_MIN) {
            Terminal.setFont(Terminal.getFont().deriveFont(Terminal.getFont().getSize() - 1f));
        } else {
            Terminal.setFont(Terminal.getFont().deriveFont(TERMINAL_FONT_SIZE_MIN));
        }
        prefs.putFloat(TERMINAL_FONT_SIZE, Terminal.getFont().getSize());
        PrefsFlush();
    }//GEN-LAST:event_MenuItemViewTermFontDecActionPerformed

    private void MenuItemViewEditorFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewEditorFontIncActionPerformed
        int size = TextEditor1.get(iTab).getFont().getSize();
        if (size < EDITOR_FONT_SIZE_MAX) {
            TextEditor1.get(iTab).setFont(TextEditor1.get(iTab).getFont().deriveFont(TextEditor1.get(iTab).getFont().getSize() + 1f));
        } else {
            TextEditor1.get(iTab).setFont(TextEditor1.get(iTab).getFont().deriveFont(EDITOR_FONT_SIZE_MAX));
        }
        prefs.putFloat(EDITOR_FONT_SIZE, TextEditor1.get(iTab).getFont().getSize());
        PrefsFlush();
        SetTheme(prefs.getInt(COLOR_THEME, 0), true); // for all
    }//GEN-LAST:event_MenuItemViewEditorFontIncActionPerformed

    private void MenuItemViewEditorFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewEditorFontDecActionPerformed
        int size = TextEditor1.get(iTab).getFont().getSize();
        if (size > EDITOR_FONT_SIZE_MIN) {
            TextEditor1.get(iTab).setFont(TextEditor1.get(iTab).getFont().deriveFont(TextEditor1.get(iTab).getFont().getSize() - 1f));
        } else {
            TextEditor1.get(iTab).setFont(TextEditor1.get(iTab).getFont().deriveFont(EDITOR_FONT_SIZE_MIN));
        }
        prefs.putFloat(EDITOR_FONT_SIZE, TextEditor1.get(iTab).getFont().getSize());
        PrefsFlush();
        SetTheme(prefs.getInt(COLOR_THEME, 0), true); // for all
    }//GEN-LAST:event_MenuItemViewEditorFontDecActionPerformed

    private void MenuItemViewFontDefaultActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewFontDefaultActionPerformed
        prefs.putFloat(TERMINAL_FONT_SIZE, TERMINAL_FONT_SIZE_DEFAULT);
        prefs.putFloat(EDITOR_FONT_SIZE, EDITOR_FONT_SIZE_DEFAULT);
        prefs.putFloat(LOG_FONT_SIZE, LOG_FONT_SIZE_DEFAULT);
        PrefsFlush();
        SetTheme(prefs.getInt(COLOR_THEME, 0), true); // for all
        Terminal.setFont(Terminal.getFont().deriveFont(TERMINAL_FONT_SIZE_DEFAULT));
        Log.setFont(Log.getFont().deriveFont(LOG_FONT_SIZE_DEFAULT));
    }//GEN-LAST:event_MenuItemViewFontDefaultActionPerformed

    private void MenuItemEditorFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorFontIncActionPerformed
        MenuItemViewEditorFontInc.doClick();
    }//GEN-LAST:event_MenuItemEditorFontIncActionPerformed

    private void MenuItemEditorFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemEditorFontDecActionPerformed
        MenuItemViewEditorFontDec.doClick();
    }//GEN-LAST:event_MenuItemEditorFontDecActionPerformed

    private void MenuItemViewLogFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewLogFontIncActionPerformed
        int size = Log.getFont().getSize();
        if (size < LOG_FONT_SIZE_MAX) {
            Log.setFont(Log.getFont().deriveFont(Log.getFont().getSize() + 1f));
        } else {
            Log.setFont(Log.getFont().deriveFont(LOG_FONT_SIZE_MAX));
        }
        prefs.putFloat(LOG_FONT_SIZE, Log.getFont().getSize());
        PrefsFlush();
    }//GEN-LAST:event_MenuItemViewLogFontIncActionPerformed

    private void MenuItemViewLogFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewLogFontDecActionPerformed
        int size = Log.getFont().getSize();
        if (size > LOG_FONT_SIZE_MIN) {
            Log.setFont(Log.getFont().deriveFont(Log.getFont().getSize() - 1f));
        } else {
            Log.setFont(Log.getFont().deriveFont(LOG_FONT_SIZE_MIN));
        }
        prefs.putFloat(LOG_FONT_SIZE, Log.getFont().getSize());
        PrefsFlush();
    }//GEN-LAST:event_MenuItemViewLogFontDecActionPerformed

    private void MenuItemLogFontIncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLogFontIncActionPerformed
        MenuItemViewLogFontInc.doClick();
    }//GEN-LAST:event_MenuItemLogFontIncActionPerformed

    private void MenuItemLogFontDecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLogFontDecActionPerformed
        MenuItemViewLogFontDec.doClick();
    }//GEN-LAST:event_MenuItemLogFontDecActionPerformed

    private void SpeedItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SpeedItemStateChanged
        nSpeed = Integer.parseInt((String) Speed.getSelectedItem());

    }//GEN-LAST:event_SpeedItemStateChanged

    private void LogCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_LogCaretUpdate
    }//GEN-LAST:event_LogCaretUpdate

    private void MenuItemESPResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemESPResetActionPerformed
        if (LeftTab.getSelectedIndex() == 0) {              // NodeMCU TAB
            cmdNodeRestart.doClick();
        } else if (LeftTab.getSelectedIndex() == 1) {     // AT TAB
            AT_Restart.doClick();
        }
    }//GEN-LAST:event_MenuItemESPResetActionPerformed

    private void MenuItemESPFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemESPFormatActionPerformed
        if (LeftTab.getSelectedIndex() == 0) {              // NodeMCU TAB
            int isFormat = Dialog("格式化ESP flash数据区和删除所有文件。你确定吗？", JOptionPane.YES_NO_OPTION);
            if (isFormat == JOptionPane.YES_OPTION) {
                btnSend("file.format()");
            }
        }
    }//GEN-LAST:event_MenuItemESPFormatActionPerformed

    private void MenuItemTerminalFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemTerminalFormatActionPerformed
        MenuItemESPFormat.doClick();
    }//GEN-LAST:event_MenuItemTerminalFormatActionPerformed

    private void MenuItemLinksNodeMCUdocActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksNodeMCUdocActionPerformed
        goLink(api_en_uri);
    }//GEN-LAST:event_MenuItemLinksNodeMCUdocActionPerformed

    private void MenuItemLinksMicroPythonDocActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksMicroPythonDocActionPerformed
        goLink(micropython_doc);
    }//GEN-LAST:event_MenuItemLinksMicroPythonDocActionPerformed

    private void MenuItemESPFileDoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemESPFileDoActionPerformed

    }//GEN-LAST:event_MenuItemESPFileDoActionPerformed

    private void MenuItemESPFileDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemESPFileDeleteActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MenuItemESPFileDeleteActionPerformed

    private void ContextMenuESPFileLUAPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_ContextMenuESPFileLUAPopupMenuWillBecomeVisible

    }//GEN-LAST:event_ContextMenuESPFileLUAPopupMenuWillBecomeVisible

    private void TerminalPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_TerminalPropertyChange

    }//GEN-LAST:event_TerminalPropertyChange

    private void RightFilesSplitPanePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_RightFilesSplitPanePropertyChange
        if ("dividerLocation".equals(evt.getPropertyName()) && MenuItemViewFileManager.isSelected()) {
            prefs.putInt(FM_DIV, RightFilesSplitPane.getDividerLocation());
        }
    }//GEN-LAST:event_RightFilesSplitPanePropertyChange

    private void RightBigPanePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_RightBigPanePropertyChange

    }//GEN-LAST:event_RightBigPanePropertyChange

    private void formPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_formPropertyChange
        //log(evt.getPropertyName());
    }//GEN-LAST:event_formPropertyChange

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        isFileManagerShow();
    }//GEN-LAST:event_formComponentResized

    private void FileListReloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileListReloadActionPerformed
        NodeListFiles();
    }//GEN-LAST:event_FileListReloadActionPerformed

    private void FileAsButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileAsButton1ActionPerformed
        String fn = evt.getActionCommand();
        if (fn.endsWith(".lua") || fn.endsWith(".lc")) {
            String cmd = "dofile(\"" + fn + "\")";
            btnSend(cmd);
        } else if (fn.endsWith(".bin") || fn.endsWith(".dat")) {
            HexDump(fn);
        } else {
            ViewFile(fn);
        }
    }//GEN-LAST:event_FileAsButton1ActionPerformed

    private void FileAsButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_FileAsButton1MouseClicked

    }//GEN-LAST:event_FileAsButton1MouseClicked

    private void NodeInfoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NodeInfoActionPerformed
        btnSend("=node.info()");
    }//GEN-LAST:event_NodeInfoActionPerformed

    private void NodeChipIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NodeChipIDActionPerformed
        btnSend("=node.chipid()");
    }//GEN-LAST:event_NodeChipIDActionPerformed

    private void NodeFlashIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NodeFlashIDActionPerformed
        btnSend("=node.flashid()");
    }//GEN-LAST:event_NodeFlashIDActionPerformed

    private void NodeHeapActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NodeHeapActionPerformed
        btnSend("=node.heap()");
    }//GEN-LAST:event_NodeHeapActionPerformed

    private void FileFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileFormatActionPerformed
        MenuItemESPFormat.doClick();
    }//GEN-LAST:event_FileFormatActionPerformed

    private void MenuItemViewSnippetsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewSnippetsActionPerformed
        prefs.putBoolean(SHOW_SNIP_RIGHT, MenuItemViewSnippets.isSelected());
        isRightSnippetsShow();
    }//GEN-LAST:event_MenuItemViewSnippetsActionPerformed

    private void MenuItemViewFileManagerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewFileManagerActionPerformed
        prefs.putBoolean(SHOW_FM_RIGHT, MenuItemViewFileManager.isSelected());
        isFileManagerShow();
    }//GEN-LAST:event_MenuItemViewFileManagerActionPerformed

    private void MenuItemViewRightExtraActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewRightExtraActionPerformed
        RightExtraButtons.setVisible(MenuItemViewRightExtra.isSelected());
        prefs.putBoolean(SHOW_EXTRA_RIGHT, MenuItemViewRightExtra.isSelected());
    }//GEN-LAST:event_MenuItemViewRightExtraActionPerformed

    private void MenuItemFileSaveAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemFileSaveAsActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MenuItemFileSaveAsActionPerformed

    private void MenuItemViewToolbarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewToolbarActionPerformed
        prefs.putBoolean(SHOW_TOOLBAR, MenuItemViewToolbar.isSelected());
        isToolbarShow();
    }//GEN-LAST:event_MenuItemViewToolbarActionPerformed

    private void MenuItemViewLeftExtraActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewLeftExtraActionPerformed
        prefs.putBoolean(SHOW_EXTRA_LEFT, MenuItemViewLeftExtra.isSelected());
        isLeftExtraShow();
    }//GEN-LAST:event_MenuItemViewLeftExtraActionPerformed

    private void MenuViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuViewActionPerformed

    }//GEN-LAST:event_MenuViewActionPerformed

    private void RightSplitPanePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_RightSplitPanePropertyChange
        if ("dividerLocation".equals(evt.getPropertyName()) && MenuItemViewLog.isSelected()) {
            prefs.putInt(LOG_DIV, RightSplitPane.getDividerLocation());
        }
    }//GEN-LAST:event_RightSplitPanePropertyChange

    private void AutoScrollActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AutoScrollActionPerformed
        prefs.putBoolean(AUTO_SCROLL, AutoScroll.isSelected());
    }//GEN-LAST:event_AutoScrollActionPerformed

    private void PortDTRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PortDTRActionPerformed
        prefs.putBoolean(PORT_DTR, PortDTR.isSelected());
        try {
            serialPort.setDTR(PortDTR.isSelected());
            if (PortDTR.isSelected()) {
                log("DTR设置为开");
            } else {
                log("DTR设置为关");
            }
        } catch (Exception e) {
            PortDTR.setSelected(false);
            log(e.toString());
            log("无法更改DTR的状态");
        }
        UpdateLED();
    }//GEN-LAST:event_PortDTRActionPerformed

    private void PortRTSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PortRTSActionPerformed
        prefs.putBoolean(PORT_RTS, PortRTS.isSelected());
        try {
            serialPort.setRTS(PortRTS.isSelected());
            if (PortRTS.isSelected()) {
                log("RTS设置为开");
            } else {
                log("RTS设置为关");
            }
        } catch (Exception e) {
            PortRTS.setSelected(false);
            log(e.toString());
            log("无法改变RTS的状态");
        }
        UpdateLED();
    }//GEN-LAST:event_PortRTSActionPerformed

    private void MenuItemViewToolbarItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewToolbarItemStateChanged
        prefs.putBoolean(SHOW_TOOLBAR, MenuItemViewToolbar.isSelected());
        isToolbarShow();
    }//GEN-LAST:event_MenuItemViewToolbarItemStateChanged

    private void MenuItemViewLeftExtraItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewLeftExtraItemStateChanged
        prefs.putBoolean(SHOW_EXTRA_LEFT, MenuItemViewLeftExtra.isSelected());
        isLeftExtraShow();
    }//GEN-LAST:event_MenuItemViewLeftExtraItemStateChanged

    private void MenuItemViewSnippetsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewSnippetsItemStateChanged
        prefs.putBoolean(SHOW_SNIP_RIGHT, MenuItemViewSnippets.isSelected());
        isRightSnippetsShow();
    }//GEN-LAST:event_MenuItemViewSnippetsItemStateChanged

    private void MenuItemViewFileManagerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewFileManagerItemStateChanged
        prefs.putBoolean(SHOW_FM_RIGHT, MenuItemViewFileManager.isSelected());
        ShowFileManager.setSelected(MenuItemViewFileManager.isSelected());
        isFileManagerShow();
    }//GEN-LAST:event_MenuItemViewFileManagerItemStateChanged

    private void MenuItemViewRightExtraItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewRightExtraItemStateChanged
        RightExtraButtons.setVisible(MenuItemViewRightExtra.isSelected());
        prefs.putBoolean(SHOW_EXTRA_RIGHT, MenuItemViewRightExtra.isSelected());
    }//GEN-LAST:event_MenuItemViewRightExtraItemStateChanged

    private void MenuItemViewLogItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewLogItemStateChanged
        isLogShow();
        prefs.putBoolean(SHOW_LOG, MenuItemViewLog.isSelected());
    }//GEN-LAST:event_MenuItemViewLogItemStateChanged

    private void FileSystemInfoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileSystemInfoActionPerformed
        NodeFileSystemInfo();
    }//GEN-LAST:event_FileSystemInfoActionPerformed

    private void FileRenameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileRenameActionPerformed
        btnSend("file.rename(\"" + FileRenameLabel.getText() + "\",\"" + FileRename.getText().trim() + "\")");
        try {
            Thread.sleep(200L);
        } catch (Exception e) {
        }
        FileListReload.doClick();
    }//GEN-LAST:event_FileRenameActionPerformed

    private void MenuItemViewDonateItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewDonateItemStateChanged
        DonateSmall.setVisible(!MenuItemViewDonate.isSelected());
        prefs.putBoolean(SHOW_DONATE, MenuItemViewDonate.isSelected());
    }//GEN-LAST:event_MenuItemViewDonateItemStateChanged

    private void MenuItemViewDonateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewDonateActionPerformed
        // nothing
    }//GEN-LAST:event_MenuItemViewDonateActionPerformed

    private void MenuItemLinksBuyDevBoardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksBuyDevBoardActionPerformed
        goLink(buy_nodeMCU);
    }//GEN-LAST:event_MenuItemLinksBuyDevBoardActionPerformed

    private void MenuItemLinksBuyESP8266ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksBuyESP8266ActionPerformed
        goLink(buy_esp8266);
    }//GEN-LAST:event_MenuItemLinksBuyESP8266ActionPerformed

    private void MenuItemLinksBuyESD12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksBuyESD12ActionPerformed
        goLink(buy_esd12);
    }//GEN-LAST:event_MenuItemLinksBuyESD12ActionPerformed

    private void MenuItemLinksESPlorerForumEnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksESPlorerForumEnActionPerformed
        goLink(esp8266com_uri);
    }//GEN-LAST:event_MenuItemLinksESPlorerForumEnActionPerformed

    private void MenuItemLinksESPlorerForumRuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksESPlorerForumRuActionPerformed
        goLink(esp8266ru_uri);
    }//GEN-LAST:event_MenuItemLinksESPlorerForumRuActionPerformed

    private void MenuItemLinksESPlorerLatestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksESPlorerLatestActionPerformed
        goLink(esplorer_latest);
    }//GEN-LAST:event_MenuItemLinksESPlorerLatestActionPerformed

    private void MenuItemLinksESPlorerSourceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksESPlorerSourceActionPerformed
        goLink(esplorer_source);
    }//GEN-LAST:event_MenuItemLinksESPlorerSourceActionPerformed

    private void MenuItemLinksESPlorerHomeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksESPlorerHomeActionPerformed
        goLink(homepage_uri);
    }//GEN-LAST:event_MenuItemLinksESPlorerHomeActionPerformed

    private void MenuItemLinksDonateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksDonateActionPerformed
        goLink(donate_uri);
    }//GEN-LAST:event_MenuItemLinksDonateActionPerformed

    private void MenuItemLinksBuyOtherActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksBuyOtherActionPerformed
        goLink(buy_other);
    }//GEN-LAST:event_MenuItemLinksBuyOtherActionPerformed

    private void formWindowGainedFocus(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowGainedFocus

    }//GEN-LAST:event_formWindowGainedFocus

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        AppClose();
    }//GEN-LAST:event_formWindowClosing
    private void AppClose() {
        Rectangle r = this.getBounds();
        prefs.putInt(WIN_X, r.x);
        prefs.putInt(WIN_Y, r.y);
        prefs.putInt(WIN_H, r.height);
        prefs.putInt(WIN_W, r.width);
        //log("w="+Integer.toString(prefs.getInt(WIN_W, 0)));
        while (FilesTabbedPane.getTabCount() > 0) {
            if (CloseFile() == JOptionPane.CANCEL_OPTION) {
                return;
            }
            if ((FilesTabbedPane.getTabCount() == 1) && isFileNew()) {
                break;
            }
        }
        this.setVisible(false);
        System.exit(0);
    }
    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        // TODO add your handling code here:
    }//GEN-LAST:event_formWindowClosed

    private void EOLItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_EOLItemStateChanged
        Terminal.setEOLMarkersVisible(EOL.isSelected());
    }//GEN-LAST:event_EOLItemStateChanged

    private void MenuItemViewLookAndFeelActionPerformed(java.awt.event.ActionEvent evt) {                                                
        String lclass = evt.getActionCommand();
        prefs.put("LAF", lclass);
        try {
            UIManager.setLookAndFeel(lclass);
            SwingUtilities.updateComponentTreeUI(this);
            this.pack();
            this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(ESPlorer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    private void MenuItemViewTerminalOnlyItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewTerminalOnlyItemStateChanged
        if (MenuItemViewTerminalOnly.isSelected()) {
            MenuItemViewEditorOnly.setSelected(false);
            TerminalOnlyCheckBox.setSelected(true);
            EditorOnlyCheckBox.setSelected(false);
            HorizontSplit.setDividerLocation(0);
        } else {
            TerminalOnlyCheckBox.setSelected(false);
            HorizontSplit.setDividerLocation(550);
        }
    }//GEN-LAST:event_MenuItemViewTerminalOnlyItemStateChanged

    private void MenuItemViewTerminalOnlyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewTerminalOnlyActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MenuItemViewTerminalOnlyActionPerformed

    private void TerminalOnlyCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_TerminalOnlyCheckBoxItemStateChanged
        MenuItemViewTerminalOnly.setSelected(TerminalOnlyCheckBox.isSelected());
    }//GEN-LAST:event_TerminalOnlyCheckBoxItemStateChanged

    private void ShowFileManagerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_ShowFileManagerItemStateChanged
        MenuItemViewFileManager.setSelected(ShowFileManager.isSelected());
    }//GEN-LAST:event_ShowFileManagerItemStateChanged

    private void AboutWindowLostFocus(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_AboutWindowLostFocus
        About.dispose();
    }//GEN-LAST:event_AboutWindowLostFocus

    private void LeftTabStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_LeftTabStateChanged
        if (LeftTab.getSelectedIndex() == 0) {  // NodeMCU & Python
            if (FirmwareType == FIRMWARE_MPYTHON || OptionMicroPython.isSelected()) {
                CommandsSetMicroPython();
            } else {
                CommandsSetNodeMCU();
            }
        } else if (LeftTab.getSelectedIndex() == 1) {  // AT
            FirmwareType = FIRMWARE_AT;
            CommandsSetAT();
        } else if (LeftTab.getSelectedIndex() == 2) {  // RN2483
            if (pOpen && nSpeed != 57600) {
                TerminalAdd("\r\n警告！RN2483默认波特率为57600！\r\n");
            }
        }
    }//GEN-LAST:event_LeftTabStateChanged

    private void cmdSetCWDHCPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWDHCPActionPerformed
        btnSend("AT+CWDHCP=" + Integer.toString(DHCPmode.getSelectedIndex()) + "," + Integer.toString(DHCP.getSelectedIndex()));
    }//GEN-LAST:event_cmdSetCWDHCPActionPerformed

    private void cmdSetCWMODE3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWMODE3ActionPerformed
        btnSend("AT+CWMODE=3");
    }//GEN-LAST:event_cmdSetCWMODE3ActionPerformed

    private void cmdSetCWLAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWLAPActionPerformed
        btnSend("AT+CWLAP");
    }//GEN-LAST:event_cmdSetCWLAPActionPerformed

    private void cmdSetCWMODE2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWMODE2ActionPerformed
        btnSend("AT+CWMODE=2");
    }//GEN-LAST:event_cmdSetCWMODE2ActionPerformed

    private void cmdGetCWMODEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCWMODEActionPerformed
        btnSend("AT+CWMODE?");
    }//GEN-LAST:event_cmdGetCWMODEActionPerformed

    private void cmdSetCWMODE1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWMODE1ActionPerformed
        btnSend("AT+CWMODE=1");
    }//GEN-LAST:event_cmdSetCWMODE1ActionPerformed

    private void cmdGetHelpCWMODEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetHelpCWMODEActionPerformed
        btnSend("AT+CWMODE=?");
    }//GEN-LAST:event_cmdGetHelpCWMODEActionPerformed

    private void cmdGetCIFSRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIFSRActionPerformed
        btnSend("AT+CIFSR");
    }//GEN-LAST:event_cmdGetCIFSRActionPerformed

    private void cmdSetCIPMUX0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPMUX0ActionPerformed
        btnSend("AT+CIPMUX=0");
    }//GEN-LAST:event_cmdSetCIPMUX0ActionPerformed

    private void cmdSetCIPMUX1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPMUX1ActionPerformed
        btnSend("AT+CIPMUX=1");
    }//GEN-LAST:event_cmdSetCIPMUX1ActionPerformed

    private void cmdGetCIPMUXActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPMUXActionPerformed
        btnSend("AT+CIPMUX?");
    }//GEN-LAST:event_cmdGetCIPMUXActionPerformed

    private void cmdGetCIPSTATUSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPSTATUSActionPerformed
        btnSend("AT+CIPSTATUS");
    }//GEN-LAST:event_cmdGetCIPSTATUSActionPerformed

    private void AT_ServerComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_AT_ServerComponentShown
        WiFi_common.setVisible(false);
        TCP_common.setVisible(true);
    }//GEN-LAST:event_AT_ServerComponentShown

    private void AT_ServerFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_AT_ServerFocusGained

    }//GEN-LAST:event_AT_ServerFocusGained

    private void cmdSetCIPSTOActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPSTOActionPerformed
        btnSend("AT+CIPSTO=" + ServerTimeout.getText().trim());
    }//GEN-LAST:event_cmdSetCIPSTOActionPerformed

    private void cmdGetCIPSTOActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPSTOActionPerformed
        btnSend("AT+CIPSTO?");
    }//GEN-LAST:event_cmdGetCIPSTOActionPerformed

    private void ServerModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ServerModeActionPerformed
        if (ServerMode.getSelectedIndex() == 1) { // create
            ServerPort.setEnabled(true);
        } else {
            ServerPort.setEnabled(false);
        }
    }//GEN-LAST:event_ServerModeActionPerformed

    private void cmdSetCIPSERVERActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPSERVERActionPerformed
        String cmd = "AT+CIPSERVER=";
        cmd += Integer.toString(ServerMode.getSelectedIndex()).trim();
        if (ServerMode.getSelectedIndex() == 1) {
            cmd += "," + ServerPort.getText().trim();
        }
        btnSend(cmd);
    }//GEN-LAST:event_cmdSetCIPSERVERActionPerformed

    private void cmdSetCIPMODE1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPMODE1ActionPerformed
        btnSend("AT+CIPMODE=1");
    }//GEN-LAST:event_cmdSetCIPMODE1ActionPerformed

    private void cmdSetCIPMODE0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPMODE0ActionPerformed
        btnSend("AT+CIPMODE=0");
    }//GEN-LAST:event_cmdSetCIPMODE0ActionPerformed

    private void cmdGetCIPMODEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPMODEActionPerformed
        btnSend("AT+CIPMODE?");
    }//GEN-LAST:event_cmdGetCIPMODEActionPerformed

    private void AT_ClientComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_AT_ClientComponentShown
        WiFi_common.setVisible(false);
        TCP_common.setVisible(true);
    }//GEN-LAST:event_AT_ClientComponentShown

    private void AT_ClientFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_AT_ClientFocusGained

    }//GEN-LAST:event_AT_ClientFocusGained

    private void cmdSetCIPCLOSEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPCLOSEActionPerformed
        String cmd = "AT+CIPCLOSE";
        if (multi.isSelected()) {
            cmd += "=" + conn_id.getSelectedItem().toString();
        }
        btnSend(cmd);
    }//GEN-LAST:event_cmdSetCIPCLOSEActionPerformed

    private void cmdCIPSENDinteractiveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdCIPSENDinteractiveActionPerformed
        btnSend("AT+CIPSEND");
    }//GEN-LAST:event_cmdCIPSENDinteractiveActionPerformed

    private void cmdCIPSENDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdCIPSENDActionPerformed
        String cmd = "AT+CIPSEND=";
        String len = Integer.toString(data.getText().length());
        if (multi.isSelected()) {
            cmd += conn_id.getSelectedItem().toString() + ",";
        }
        cmd += len;
        btnSend(cmd);
        btnSend(data.getText());
    }//GEN-LAST:event_cmdCIPSENDActionPerformed

    private void cmdSetCIPSTARTActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPSTARTActionPerformed
        String cmd = "AT+CIPSTART=";
        if (multi.isSelected()) {
            cmd += conn_id.getSelectedItem().toString() + ",";
            btnSend("AT+CIPMUX=1");
        } else {
            btnSend("AT+CIPMUX=0");
        }
        if (protocol.getSelectedIndex() == 0) { // TCP
            cmd += "\"TCP\",\"";
        } else {
            cmd += "\"UDP\",\"";
        }
        cmd += remote_address.getText().trim() + "\"," + remote_port.getText().trim();
        if ((udp_local_port.getText().trim() != "") && (protocol.getSelectedIndex() == 1)) {
            cmd += "," + udp_local_port.getText().trim() + "," + udp_mode.getText().trim();
        }
        btnSend(cmd);
    }//GEN-LAST:event_cmdSetCIPSTARTActionPerformed

    private void protocolItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_protocolItemStateChanged
        if (protocol.getSelectedIndex() == 0) { // TCP
            udp_local_port.setEnabled(false);
            udp_mode.setEnabled(false);
        } else {
            udp_local_port.setEnabled(true);
            udp_mode.setEnabled(true);
        }

    }//GEN-LAST:event_protocolItemStateChanged

    private void UDPPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_UDPPropertyChange

    }//GEN-LAST:event_UDPPropertyChange

    private void cmdGetCIPSTARTActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPSTARTActionPerformed
        btnSend("AT+CIPSTART=?");
    }//GEN-LAST:event_cmdGetCIPSTARTActionPerformed

    private void multiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_multiActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_multiActionPerformed

    private void multiItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_multiItemStateChanged

    }//GEN-LAST:event_multiItemStateChanged

    private void singleItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_singleItemStateChanged

    }//GEN-LAST:event_singleItemStateChanged

    private void AT_SoftAPComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_AT_SoftAPComponentShown
        WiFi_common.setVisible(true);
        TCP_common.setVisible(false);
    }//GEN-LAST:event_AT_SoftAPComponentShown

    private void AT_SoftAPFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_AT_SoftAPFocusGained

    }//GEN-LAST:event_AT_SoftAPFocusGained

    private void cmdSetCIPAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPAPActionPerformed
        btnSend("AT+CIPAP=\"" + softAPIP.getText() + "\"");
    }//GEN-LAST:event_cmdSetCIPAPActionPerformed

    private void cmdSetCIPAPMACActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPAPMACActionPerformed
        btnSend("AT+CIPAPMAC=\"" + MAC.getText() + "\"");
    }//GEN-LAST:event_cmdSetCIPAPMACActionPerformed

    private void cmdGetCIPAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPAPActionPerformed
        btnSend("AT+CIPAP?");
    }//GEN-LAST:event_cmdGetCIPAPActionPerformed

    private void PASSsoftAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PASSsoftAPActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_PASSsoftAPActionPerformed

    private void PASSsoftAPFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_PASSsoftAPFocusGained
        // TODO add your handling code here:
    }//GEN-LAST:event_PASSsoftAPFocusGained

    private void SSIDsoftAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SSIDsoftAPActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_SSIDsoftAPActionPerformed

    private void SSIDsoftAPFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_SSIDsoftAPFocusGained
        // TODO add your handling code here:
    }//GEN-LAST:event_SSIDsoftAPFocusGained

    private void cmdGetCWLIFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCWLIFActionPerformed
        btnSend("AT+CWLIF");
    }//GEN-LAST:event_cmdGetCWLIFActionPerformed

    private void cmdGetCIPAPMACActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPAPMACActionPerformed
        btnSend("AT+CIPAPMAC?");
    }//GEN-LAST:event_cmdGetCIPAPMACActionPerformed

    private void cmdGetCWSAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCWSAPActionPerformed
        btnSend("AT+CWSAP?");
    }//GEN-LAST:event_cmdGetCWSAPActionPerformed

    private void cmdSetCWSAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWSAPActionPerformed
        int ch = channel.getSelectedIndex() + 1;
        btnSend("AT+CWSAP=\"" + SSIDsoftAP.getText() + "\",\"" + PASSsoftAP.getText() + "\"," + Integer.toString(ch) + "," + encryption.getSelectedIndex());
    }//GEN-LAST:event_cmdSetCWSAPActionPerformed

    private void AT_StationComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_AT_StationComponentShown
        WiFi_common.setVisible(true);
        TCP_common.setVisible(false);
    }//GEN-LAST:event_AT_StationComponentShown

    private void AT_StationFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_AT_StationFocusGained

    }//GEN-LAST:event_AT_StationFocusGained

    private void cmdSetCIPSTAActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPSTAActionPerformed
        btnSend("AT+CIPSTA=\"" + StationIP.getText() + "\"");
    }//GEN-LAST:event_cmdSetCIPSTAActionPerformed

    private void cmdGetCIPSTAActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPSTAActionPerformed
        btnSend("AT+CIPSTA?");
    }//GEN-LAST:event_cmdGetCIPSTAActionPerformed

    private void cmdSetCIPSTAMACActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCIPSTAMACActionPerformed
        btnSend("AT+CIPSTAMAC=\"" + MAC.getText() + "\"");
    }//GEN-LAST:event_cmdSetCIPSTAMACActionPerformed

    private void cmdGetCIPSTAMACActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCIPSTAMACActionPerformed
        btnSend("AT+CIPSTAMAC?");
    }//GEN-LAST:event_cmdGetCIPSTAMACActionPerformed

    private void cmdSetCWQAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWQAPActionPerformed
        btnSend("AT+CWQAP");
    }//GEN-LAST:event_cmdSetCWQAPActionPerformed

    private void PASSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PASSActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_PASSActionPerformed

    private void PASSFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_PASSFocusGained
        if (PASS.getText().trim().equals("WIFI密码")) {
            PASS.setText("");
        }
    }//GEN-LAST:event_PASSFocusGained

    private void SSIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SSIDActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_SSIDActionPerformed

    private void SSIDFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_SSIDFocusGained
        if (SSID.getText().trim().equals("WIFI名称")) {
            SSID.setText("");
        }
    }//GEN-LAST:event_SSIDFocusGained

    private void cmdSetCWJAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetCWJAPActionPerformed
        btnSend("AT+CWJAP=\"" + SSID.getText() + "\",\"" + PASS.getText() + "\"");
    }//GEN-LAST:event_cmdSetCWJAPActionPerformed

    private void cmdGetCWJAPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdGetCWJAPActionPerformed
        btnSend("AT+CWJAP?");
    }//GEN-LAST:event_cmdGetCWJAPActionPerformed

    private void UPDATEActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_UPDATEActionPerformed
        btnSend("AT+CIUPDATE");
    }//GEN-LAST:event_UPDATEActionPerformed

    private void ATE1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ATE1ActionPerformed
        btnSend("ATE1");
    }//GEN-LAST:event_ATE1ActionPerformed

    private void ATE0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ATE0ActionPerformed
        btnSend("ATE0");
    }//GEN-LAST:event_ATE0ActionPerformed

    private void GSLPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_GSLPActionPerformed
        btnSend("AT+GSLP=5000");
    }//GEN-LAST:event_GSLPActionPerformed

    private void AT_GMRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AT_GMRActionPerformed
        btnSend("AT+GMR");
    }//GEN-LAST:event_AT_GMRActionPerformed

    private void AT_RestartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AT_RestartActionPerformed
        btnSend("AT+RST");
    }//GEN-LAST:event_AT_RestartActionPerformed

    private void cmdATActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdATActionPerformed
        btnSend("AT");
    }//GEN-LAST:event_cmdATActionPerformed

    private void NodeMCUComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_NodeMCUComponentShown
        UpdateEditorButtons();
        UpdateButtons();
    }//GEN-LAST:event_NodeMCUComponentShown

    private void NodeMCUFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_NodeMCUFocusGained

    }//GEN-LAST:event_NodeMCUFocusGained

    private void TextTabStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_TextTabStateChanged
        if (TextTab.getSelectedIndex() == 2) { // snippets
        } else if (TextTab.getSelectedIndex() == 3) { // Settings
        } else if (TextTab.getSelectedIndex() == 1) { // Commands
        } else if (TextTab.getSelectedIndex() == 0) { // Scripts
        }
    }//GEN-LAST:event_TextTabStateChanged

    private void AutodetectFirmwareItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_AutodetectFirmwareItemStateChanged
        prefs.putBoolean(AUTODETECT, AutodetectFirmware.isSelected());
    }//GEN-LAST:event_AutodetectFirmwareItemStateChanged

    private void UseCustomPortNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_UseCustomPortNameActionPerformed
        Port.setEnabled(!UseCustomPortName.isSelected());
        Port.setVisible(!UseCustomPortName.isSelected());
        CustomPortName.setEnabled(UseCustomPortName.isSelected());
        prefs.putBoolean(USE_CUSTOM_PORT, UseCustomPortName.isSelected());
    }//GEN-LAST:event_UseCustomPortNameActionPerformed

    private void CustomPortNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_CustomPortNameFocusLost
        prefs.put(CUSTOM_PORT_NAME, CustomPortName.getText());
    }//GEN-LAST:event_CustomPortNameFocusLost

    private void LogMaxSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_LogMaxSizeActionPerformed

    }//GEN-LAST:event_LogMaxSizeActionPerformed

    private void LogMaxSizeFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_LogMaxSizeFocusLost
        try {
            LogMax = Integer.parseInt(LogMaxSize.getText()) * 1024;
        } catch (Exception e) {
            LogMax = 1024 * 10;
        }
        if (LogMax < 2048) {
            LogMax = 2048;
        } else if (LogMax > 32 * 1024) {
            LogMax = 32 * 1024;
        }
        prefs.putInt(LOG_MAX_SIZE, LogMax);
        log("日志缓存大小设置为 " + Integer.toString(LogMax / 1024) + " KB", DEBUG);
    }//GEN-LAST:event_LogMaxSizeFocusLost

    private void TerminalMaxSizeFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_TerminalMaxSizeFocusLost
        try {
            TerminalMax = Integer.parseInt(TerminalMaxSize.getText()) * 1024;
        } catch (Exception e) {
            TerminalMax = 1024 * 100;
        }
        if (TerminalMax < 2048) {
            TerminalMax = 2048;
        } else if (TerminalMax > 1024 * 1024) {
            TerminalMax = 1024 * 1024;
        }
        prefs.putInt(TERMINAL_MAX_SIZE, TerminalMax);
        log("终端缓存大小设置为 " + Integer.toString(TerminalMax / 1024) + " KB", DEBUG);
    }//GEN-LAST:event_TerminalMaxSizeFocusLost

    private void TurboModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_TurboModeActionPerformed
        if (TurboMode.isSelected()) {
            DumbMode.setEnabled(false);
            DumbMode.setSelected(false);
        } else {
            DumbMode.setEnabled(true);
        }
        prefs.putBoolean(TURBO_MODE, TurboMode.isSelected());
        PrefsFlush();
    }//GEN-LAST:event_TurboModeActionPerformed

    private void TurboModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_TurboModeItemStateChanged

    }//GEN-LAST:event_TurboModeItemStateChanged

    private void LineDelayStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_LineDelayStateChanged
        LineDelayLabel.setText("“开环模式”的线路延迟 = " + Integer.toString(LineDelay.getValue()) + "毫秒");
        prefs.putInt(LINE_DELAY, LineDelay.getValue());
        PrefsFlush();
    }//GEN-LAST:event_LineDelayStateChanged

    private void DumbModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_DumbModeItemStateChanged
        if (DumbMode.isSelected()) {
            DelayLabel.setEnabled(false);
            Delay.setEnabled(false);
            AnswerDelayLabel.setEnabled(false);
            AnswerDelay.setEnabled(false);
            LineDelayLabel.setEnabled(true);
            LineDelay.setEnabled(true);
            TurboMode.setSelected(false);
            TurboMode.setEnabled(false);
        } else {
            DelayLabel.setEnabled(true);
            Delay.setEnabled(true);
            AnswerDelayLabel.setEnabled(true);
            AnswerDelay.setEnabled(true);
            LineDelayLabel.setEnabled(false);
            LineDelay.setEnabled(false);
            TurboMode.setEnabled(true);
        }
        prefs.putBoolean(DUMB_MODE, DumbMode.isSelected());
        PrefsFlush();
    }//GEN-LAST:event_DumbModeItemStateChanged

    private void AnswerDelayStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_AnswerDelayStateChanged
        AnswerDelayLabel.setText("回应超时时间 = " + Integer.toString(AnswerDelay.getValue()) + "秒");
        prefs.putInt(TIMEOUT, AnswerDelay.getValue());
        PrefsFlush();
    }//GEN-LAST:event_AnswerDelayStateChanged

    private void DelayStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_DelayStateChanged
        DelayLabel.setText("回应后延迟 = " + Integer.toString(Delay.getValue()) + "毫秒");
        prefs.putInt(DELAY, Delay.getValue());
        PrefsFlush();
    }//GEN-LAST:event_DelayStateChanged

    private void UseExternalEditorItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_UseExternalEditorItemStateChanged
        prefs.putBoolean(USE_EXT_EDITOR, UseExternalEditor.isSelected());
        UpdateButtons();
    }//GEN-LAST:event_UseExternalEditorItemStateChanged

    private void EditorThemeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EditorThemeActionPerformed
        int n = EditorTheme.getSelectedIndex();
        prefs.putInt(COLOR_THEME, n);
        PrefsFlush();
        SetTheme(n, true); // for all
    }//GEN-LAST:event_EditorThemeActionPerformed

    private void FileAutoRunItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_FileAutoRunItemStateChanged
        prefs.putBoolean(FILE_AUTO_RUN, FileAutoRun.isSelected());
        PrefsFlush();
    }//GEN-LAST:event_FileAutoRunItemStateChanged

    private void FileAutoSaveESPItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_FileAutoSaveESPItemStateChanged
        prefs.putBoolean(FILE_AUTO_SAVE_ESP, FileAutoSaveESP.isSelected());
        PrefsFlush();
    }//GEN-LAST:event_FileAutoSaveESPItemStateChanged

    private void FileAutoSaveDiskItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_FileAutoSaveDiskItemStateChanged
        prefs.putBoolean(FILE_AUTO_SAVE_DISK, FileAutoSaveDisk.isSelected());
        PrefsFlush();
    }//GEN-LAST:event_FileAutoSaveDiskItemStateChanged

    private void OptionMicroPythonItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_OptionMicroPythonItemStateChanged
        if (OptionMicroPython.isSelected()) {
            SetFirmwareType(FIRMWARE_MPYTHON);
        }
    }//GEN-LAST:event_OptionMicroPythonItemStateChanged

    private void OptionNodeMCUItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_OptionNodeMCUItemStateChanged
        if (OptionNodeMCU.isSelected()) {
            SetFirmwareType(FIRMWARE_NODEMCU);
        }
    }//GEN-LAST:event_OptionNodeMCUItemStateChanged

    private void CondensedItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_CondensedItemStateChanged
        prefs.putBoolean(CONDENSED, Condensed.isSelected());
    }//GEN-LAST:event_CondensedItemStateChanged

    private void SnippetCancelEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetCancelEditActionPerformed
        if (SnippetText.canUndo() || SnippetText.canRedo()) {
            this.setAlwaysOnTop(false);
            int returnVal = JOptionPane.showConfirmDialog(null, "放弃任何更改并取消编辑此代码片段而不保存?", "注意", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            this.setAlwaysOnTop(AlwaysOnTop.isSelected());
            if (returnVal != JOptionPane.YES_OPTION) {
                return;
            }
        }
        SnippetText.setEnabled(false);
        SnippetName.setEnabled(false);
        SnippetSave.setEnabled(false);
        SnippetRun.setEnabled(false);
        SnippetCancelEdit.setEnabled(false);
        SnippetText.setEnabled(false);
        SnippetScrollPane.setEnabled(false);
        SnippetText.setEditable(false);
        SnippetText.setText("");
        SnippetText.discardAllEdits();
        SnippetName.setText("");
        //SnippetText.setBackground(SnippetTopPane.getBackground());
    }//GEN-LAST:event_SnippetCancelEditActionPerformed

    private void SnippetRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetRunActionPerformed
        SendToESP(SnippetText.getText());
    }//GEN-LAST:event_SnippetRunActionPerformed

    private void SnippetSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetSaveActionPerformed
        SnippetName.setEnabled(false);
        SnippetSave.setEnabled(false);
        SnippetRun.setEnabled(true);
        SnippetCancelEdit.setEnabled(true);
        SnippetText.setEnabled(false);
        SnippetScrollPane.setEnabled(false);
        SnippetText.setEditable(false);
        //SnippetText.setBackground(SnippetTopPane.getBackground());
        SnippetText.setEnabled(false);
        if (iSnippets == 0) {
            ButtonSnippet0.setText(SnippetName.getText());
        } else if (iSnippets == 1) {
            ButtonSnippet1.setText(SnippetName.getText());
        } else if (iSnippets == 2) {
            ButtonSnippet2.setText(SnippetName.getText());
        } else if (iSnippets == 3) {
            ButtonSnippet3.setText(SnippetName.getText());
        } else if (iSnippets == 4) {
            ButtonSnippet4.setText(SnippetName.getText());
        } else if (iSnippets == 5) {
            ButtonSnippet5.setText(SnippetName.getText());
        } else if (iSnippets == 6) {
            ButtonSnippet6.setText(SnippetName.getText());
        } else if (iSnippets == 7) {
            ButtonSnippet7.setText(SnippetName.getText());
        } else if (iSnippets == 8) {
            ButtonSnippet8.setText(SnippetName.getText());
        } else if (iSnippets == 9) {
            ButtonSnippet9.setText(SnippetName.getText());
        } else if (iSnippets == 10) {
            ButtonSnippet10.setText(SnippetName.getText());
        } else if (iSnippets == 11) {
            ButtonSnippet11.setText(SnippetName.getText());
        } else if (iSnippets == 12) {
            ButtonSnippet12.setText(SnippetName.getText());
        } else if (iSnippets == 13) {
            ButtonSnippet13.setText(SnippetName.getText());
        } else if (iSnippets == 14) {
            ButtonSnippet14.setText(SnippetName.getText());
        } else {
            ButtonSnippet15.setText(SnippetName.getText());
            iSnippets = 15;
        }
        SetSnippetEditButtonsTooltip();
        Snippets[iSnippets] = SnippetText.getText();
        String suffix;
        if (OptionNodeMCU.isSelected()) {
            suffix = "";
        } else {
            suffix = "_mpy";
        }
        prefs.put("Snippet" + Integer.toString(iSnippets) + suffix + "name", SnippetName.getText());
        prefs.put("Snippet" + Integer.toString(iSnippets) + suffix, Snippets[iSnippets]);
        if (PrefsFlush()) {
            log("片段" + Integer.toString(iSnippets) + " 保存: 成功.");
        }
        SnippetText.discardAllEdits();
    }//GEN-LAST:event_SnippetSaveActionPerformed

    private void SnippetEdit15ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit15ActionPerformed
        SnippetEdit(15);
    }//GEN-LAST:event_SnippetEdit15ActionPerformed

    private void SnippetEdit14ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit14ActionPerformed
        SnippetEdit(14);
    }//GEN-LAST:event_SnippetEdit14ActionPerformed

    private void SnippetEdit13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit13ActionPerformed
        SnippetEdit(13);
    }//GEN-LAST:event_SnippetEdit13ActionPerformed

    private void SnippetEdit12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit12ActionPerformed
        SnippetEdit(12);
    }//GEN-LAST:event_SnippetEdit12ActionPerformed

    private void SnippetEdit11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit11ActionPerformed
        SnippetEdit(11);
    }//GEN-LAST:event_SnippetEdit11ActionPerformed

    private void SnippetEdit10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit10ActionPerformed
        SnippetEdit(10);
    }//GEN-LAST:event_SnippetEdit10ActionPerformed

    private void SnippetEdit9ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit9ActionPerformed
        SnippetEdit(9);
    }//GEN-LAST:event_SnippetEdit9ActionPerformed

    private void SnippetEdit8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit8ActionPerformed
        SnippetEdit(8);
    }//GEN-LAST:event_SnippetEdit8ActionPerformed

    private void SnippetEdit7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit7ActionPerformed
        SnippetEdit(7);
    }//GEN-LAST:event_SnippetEdit7ActionPerformed

    private void SnippetEdit6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit6ActionPerformed
        SnippetEdit(6);
    }//GEN-LAST:event_SnippetEdit6ActionPerformed

    private void SnippetEdit5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit5ActionPerformed
        SnippetEdit(5);
    }//GEN-LAST:event_SnippetEdit5ActionPerformed

    private void SnippetEdit4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit4ActionPerformed
        SnippetEdit(4);
    }//GEN-LAST:event_SnippetEdit4ActionPerformed

    private void SnippetEdit3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit3ActionPerformed
        SnippetEdit(3);
    }//GEN-LAST:event_SnippetEdit3ActionPerformed

    private void SnippetEdit2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit2ActionPerformed
        SnippetEdit(2);
    }//GEN-LAST:event_SnippetEdit2ActionPerformed

    private void SnippetEdit1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit1ActionPerformed
        SnippetEdit(1);
    }//GEN-LAST:event_SnippetEdit1ActionPerformed

    private void SnippetEdit0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SnippetEdit0ActionPerformed
        SnippetEdit(0);
    }//GEN-LAST:event_SnippetEdit0ActionPerformed

    private void cmdTimerStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdTimerStopActionPerformed
        String cmd = "tmr.stop(" + Integer.toString(TimerNumber.getSelectedIndex()) + ")";
        btnSend(cmd);
    }//GEN-LAST:event_cmdTimerStopActionPerformed

    private void cmdListFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdListFilesActionPerformed
        NodeListFiles();
    }//GEN-LAST:event_cmdListFilesActionPerformed

    private void cmdNodeSleepActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdNodeSleepActionPerformed
        int returnVal = Dialog("这个函数只能在esp8266 PIN32(RST)和PIN8(XPD_DCDC)连接在一起的情况下使用。", JOptionPane.YES_NO_OPTION);
        if (returnVal == JOptionPane.YES_OPTION) {
            btnSend("node.dsleep(10000)");
        }
    }//GEN-LAST:event_cmdNodeSleepActionPerformed

    private void cmdNodeHeapActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdNodeHeapActionPerformed
        btnSend("print(node.heap())");
    }//GEN-LAST:event_cmdNodeHeapActionPerformed

    private void cmdNodeChipIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdNodeChipIDActionPerformed
        btnSend("print(node.chipid())");
    }//GEN-LAST:event_cmdNodeChipIDActionPerformed

    private void cmdNodeRestartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdNodeRestartActionPerformed
        if (!OptionNodeMCU.isSelected()) {
            return;
        }
        if (portJustOpen) {
            log("错误:与MCU未建立通信。");
            return;
        }
        TerminalAdd("用命令软重启\r\n");
        btnSend("node.restart()");
        if (pOpen) { // reconnect
            int speed = prefs.getInt(SERIAL_BAUD, 3);
            final int old_speed = Speed.getSelectedIndex();
            //if (speed == old_speed) { // reconnect not needed
            //return;
            //}
            try {
                nSpeed = Integer.parseInt(Speed.getItemAt(speed).toString());
                //Integer.parseInt((String)Speed.getSelectedItem());
            } catch (Exception e) {
                return;
            }
            log("尝试重新连接保存的波特" + Integer.toString(nSpeed) + "...");
            try {
                if (SetSerialPortParams()) {
                    log("连接:成功。现在我们在等待ESP重启…");
                    // Now, we can ready to reconnect on old_speed
                    taskSleep = new ActionListener() {
                        public void actionPerformed(ActionEvent evt) {
                            if (nSpeed == 9600) {
                                CheckComm();
                            } else {
                                Speed.setSelectedIndex(old_speed);
                            }
                        }
                    };
                    sleep = new Timer(2000, taskSleep);
                    sleep.setRepeats(false);
                    sleep.setInitialDelay(2000);
                    sleep.start();
                }
            } catch (Exception e) {
                log(e.toString());
            }
        }
    }//GEN-LAST:event_cmdNodeRestartActionPerformed

    private void FilesUploadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FilesUploadActionPerformed
        //log(evt.paramString());
        UploadFiles();
    }//GEN-LAST:event_FilesUploadActionPerformed

    private void FileDoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileDoActionPerformed
        String cmd = "dofile('" + iFile.get(iTab).getName() + "')";
        btnSend(cmd);
    }//GEN-LAST:event_FileDoActionPerformed

    private void FileSendESPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileSendESPActionPerformed
        if (FileSendESP.isSelected()) {
            if (TextEditor1.get(iTab).getText().length() == 0) {
                JOptionPane.showMessageDialog(null, "空文件");
                FileSendESP.setSelected(false);
                return;
            }
            SendToESP(TextEditor1.get(iTab).getText());
        } else {
            StopSend();
        }
    }//GEN-LAST:event_FileSendESPActionPerformed

    private void FileSaveESPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileSaveESPActionPerformed
        if (!FileSaveESP.isSelected()) {
            StopSend();
            return;
        }
        if (TextEditor1.get(iTab).getText().length() == 0) {
            FileSaveESP.setSelected(false);
            JOptionPane.showMessageDialog(null, "空文件");
            return;
        }
        String fName = iFile.get(iTab).getName();
        if (fName.length() == 0) {
            FileSaveESP.setSelected(false);
            String msg = " 没有名称无法将文件保存到ESP。";
            log("ESP保存文件: 失败. " + msg);
            JOptionPane.showMessageDialog(null, msg);
            return;
        }
        if (FileAutoSaveDisk.isSelected()) {
            if (!SaveFile()) { // first save file
                FileSaveESP.setSelected(false);
                return;
            }
        }
        if (!pOpen || portJustOpen) {
            log("ESP保存文件: 串口未打开。操作取消。");
            FileSaveESP.setSelected(false);
            return;
        }
        if (OptionMicroPython.isSelected()) {
            pySaveFileESP(fName);
        } else {
            nodeSaveFileESP(fName);
        }
    }//GEN-LAST:event_FileSaveESPActionPerformed

    private void FileCompileDoLCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileCompileDoLCActionPerformed
        final String luaFileName = iFile.get(iTab).getName();
        final int extensionIndex = luaFileName.lastIndexOf(".");
        final String baseName = extensionIndex == -1 ? luaFileName : luaFileName.substring(0, extensionIndex);
        final String compiledFileName = baseName + ".lc";
        final String cmd = "node.compile('" + luaFileName + "')\r\ndofile(\"" + compiledFileName + "\")";
        btnSend(cmd);
    }//GEN-LAST:event_FileCompileDoLCActionPerformed

    private void FileUploadBinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileUploadBinActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_FileUploadBinActionPerformed

    private void FileSaveCompileDoLCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileSaveCompileDoLCActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_FileSaveCompileDoLCActionPerformed

    private void FileCompileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileCompileActionPerformed
        String cmd = "node.compile('" + iFile.get(iTab).getName() + "')";
        btnSend(cmd);
        try {
            Thread.sleep(500L);
        } catch (InterruptedException e) {
        }
        LocalEcho = false;
        FileListReload.doClick();
    }//GEN-LAST:event_FileCompileActionPerformed

    private void FileDo1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileDo1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_FileDo1ActionPerformed

    private void FilesTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_FilesTabbedPaneStateChanged
        FileLabelUpdate();
        //   if (iTab > 0) FilesTabbedPane.setTitleAt(iTab, Integer.toString(iTab));
    }//GEN-LAST:event_FilesTabbedPaneStateChanged

    private void FileLayeredPaneFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_FileLayeredPaneFocusGained

    }//GEN-LAST:event_FileLayeredPaneFocusGained

    private void TextEditorKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_TextEditorKeyTyped
        if (UseExternalEditor.isSelected()) {
            return;
        }
        if (!isChanged()) {
            FileChanged.set(iTab, true);
            UpdateEditorButtons();
        }
    }//GEN-LAST:event_TextEditorKeyTyped

    private void TextEditorInputMethodTextChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_TextEditorInputMethodTextChanged

    }//GEN-LAST:event_TextEditorInputMethodTextChanged

    private void TextEditorCaretPositionChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_TextEditorCaretPositionChanged
        UpdateEditorButtons();
    }//GEN-LAST:event_TextEditorCaretPositionChanged

    private void TextEditorActiveLineRangeChanged(org.fife.ui.rsyntaxtextarea.ActiveLineRangeEvent evt) {//GEN-FIRST:event_TextEditorActiveLineRangeChanged
        UpdateEditorButtons();
    }//GEN-LAST:event_TextEditorActiveLineRangeChanged

    private void TextEditorFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_TextEditorFocusGained

    }//GEN-LAST:event_TextEditorFocusGained

    private void TextEditorCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_TextEditorCaretUpdate
        UpdateEditorButtons();
    }//GEN-LAST:event_TextEditorCaretUpdate

    private void ButtonSendLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSendLineActionPerformed
        MenuItemEditSendLine.doClick();
    }//GEN-LAST:event_ButtonSendLineActionPerformed

    private void ButtonSendSelectedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonSendSelectedActionPerformed
        MenuItemEditSendSelected.doClick();
    }//GEN-LAST:event_ButtonSendSelectedActionPerformed

    private void ButtonPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonPasteActionPerformed
        MenuItemEditPaste.doClick();
    }//GEN-LAST:event_ButtonPasteActionPerformed

    private void ButtonCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonCopyActionPerformed
        MenuItemEditCopy.doClick();
    }//GEN-LAST:event_ButtonCopyActionPerformed

    private void ButtonCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonCutActionPerformed
        MenuItemEditCut.doClick();
    }//GEN-LAST:event_ButtonCutActionPerformed

    private void ButtonRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonRedoActionPerformed
        MenuItemEditRedo.doClick();
    }//GEN-LAST:event_ButtonRedoActionPerformed

    private void ButtonUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonUndoActionPerformed
        MenuItemEditUndo.doClick();
    }//GEN-LAST:event_ButtonUndoActionPerformed

    private void ButtonFileCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileCloseActionPerformed
        MenuItemFileClose.doClick();
    }//GEN-LAST:event_ButtonFileCloseActionPerformed

    private void ButtonFileSaveAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileSaveAllActionPerformed
        MenuItemFileSaveAll.doClick();
    }//GEN-LAST:event_ButtonFileSaveAllActionPerformed

    private void ButtonFileSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileSaveActionPerformed
        MenuItemFileSave.doClick();
    }//GEN-LAST:event_ButtonFileSaveActionPerformed

    private void ButtonFileReloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileReloadActionPerformed
        MenuItemFileReload.doClick();
    }//GEN-LAST:event_ButtonFileReloadActionPerformed

    private void ButtonFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileOpenActionPerformed
        MenuItemFileOpen.doClick();
    }//GEN-LAST:event_ButtonFileOpenActionPerformed

    private void ButtonFileNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonFileNewActionPerformed
        MenuItemFileNew.doClick();
    }//GEN-LAST:event_ButtonFileNewActionPerformed

    private void OptionNodeMCUStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_OptionNodeMCUStateChanged
        if (OptionNodeMCU.isSelected()) {
            SetFirmwareType(FIRMWARE_NODEMCU);
        }
    }//GEN-LAST:event_OptionNodeMCUStateChanged

    private void OptionMicroPythonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_OptionMicroPythonStateChanged
        if (OptionMicroPython.isSelected()) {
            SetFirmwareType(FIRMWARE_MPYTHON);
        }
    }//GEN-LAST:event_OptionMicroPythonStateChanged

    private void MicroPythonSetGPIOHigh(java.awt.event.ActionEvent evt) {
        cmdButtonGPIO(Integer.parseInt(evt.getActionCommand()), 1);
    }

    private void MicroPythonSetGPIOLow(java.awt.event.ActionEvent evt) {
        cmdButtonGPIO(Integer.parseInt(evt.getActionCommand()), 0);
    }

    private void MicroPythonGetGPIOLevel(java.awt.event.ActionEvent evt) {
        cmdButtonGetGPIO(Integer.parseInt(evt.getActionCommand()));
    }

    private void MicroPythonSSIDFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_MicroPythonSSIDFocusGained
        if (MicroPythonSSID.getText().trim().equals("WIFI名称")) {
            MicroPythonSSID.setText("");
        }
    }//GEN-LAST:event_MicroPythonSSIDFocusGained

    private void MicroPythonSSIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MicroPythonSSIDActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MicroPythonSSIDActionPerformed

    private void cmdMicroPythonStaConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMicroPythonStaConnectActionPerformed
        btnSend("import network;nic=network.WLAN(network.STA_IF);nic.active(True);nic.connect('" + MicroPythonSSID.getText() + "','" + MicroPythonPASS.getText() + "')");
    }//GEN-LAST:event_cmdMicroPythonStaConnectActionPerformed

    private void MicroPythonPASSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MicroPythonPASSActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MicroPythonPASSActionPerformed

    private void MicroPythonPASSFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_MicroPythonPASSFocusGained
        if (MicroPythonPASS.getText().trim().equals("WIFI密码")) {
            MicroPythonPASS.setText("");
        }
    }//GEN-LAST:event_MicroPythonPASSFocusGained

    private void cmdMicroPythonSendToHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMicroPythonSendToHostActionPerformed
        btnSend("import socket;"
                + "addr=socket.getaddrinfo('" + MicroPythonRemoteHost.getText() + "'," + Integer.parseInt(MicroPythonRemotePort.getText()) + ")[0][-1]\r\n"
                + "s = socket.socket();s.connect(addr);s.send(b'" + MicroPythonRemoteData.getText() + "');data = s.recv(1000);s.close()");
    }//GEN-LAST:event_cmdMicroPythonSendToHostActionPerformed

    private void cmdMicroPythonScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMicroPythonScanActionPerformed
        btnSend("import network;nic = network.WLAN(network.STA_IF);nic.scan()");
    }//GEN-LAST:event_cmdMicroPythonScanActionPerformed

    private void EditorOnlyCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_EditorOnlyCheckBoxItemStateChanged
        MenuItemViewEditorOnly.setSelected(EditorOnlyCheckBox.isSelected());
    }//GEN-LAST:event_EditorOnlyCheckBoxItemStateChanged

    private void MenuItemViewEditorOnlyItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MenuItemViewEditorOnlyItemStateChanged
        if (MenuItemViewEditorOnly.isSelected()) {
            TerminalOnlyCheckBox.setSelected(false);
            MenuItemViewTerminalOnly.setSelected(false);
            EditorOnlyCheckBox.setSelected(true);
            HorizontSplit.setDividerLocation(HorizontSplit.getWidth());
        } else {
            EditorOnlyCheckBox.setSelected(false);
            HorizontSplit.setDividerLocation(550);
        }
    }//GEN-LAST:event_MenuItemViewEditorOnlyItemStateChanged

    private void MenuItemViewEditorOnlyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemViewEditorOnlyActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_MenuItemViewEditorOnlyActionPerformed

    private void MenuItemLinksIoTmanagerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuItemLinksIoTmanagerActionPerformed
        goLink(iot_manager);
    }//GEN-LAST:event_MenuItemLinksIoTmanagerActionPerformed

    private void AlwaysOnTopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AlwaysOnTopActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_AlwaysOnTopActionPerformed

    private void PyListDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PyListDirActionPerformed
        PyListFiles();
    }//GEN-LAST:event_PyListDirActionPerformed

    private void PyFileAsButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_PyFileAsButton1MouseClicked
        // TODO add your handling code here:
    }//GEN-LAST:event_PyFileAsButton1MouseClicked

    private void PyFileAsButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PyFileAsButton1ActionPerformed
        String fn = evt.getActionCommand();
        if (fn.endsWith(".py") || fn.endsWith(".pyc")) {
            String cmd = "dofile(\"" + fn + "\")";
            btnSend(cmd);
        } else if (fn.endsWith(".bin") || fn.endsWith(".dat")) {
            //HexDump(fn);
        } else {
            //ViewFile(fn);
        }
    }//GEN-LAST:event_PyFileAsButton1ActionPerformed

    private void CommandEchoItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_CommandEchoItemStateChanged
        prefs.putBoolean(COMMAND_ECHO, CommandEcho.isSelected());
    }//GEN-LAST:event_CommandEchoItemStateChanged

    private void cmdSysResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSysResetActionPerformed
        btnSendEcho("sys reset");
    }//GEN-LAST:event_cmdSysResetActionPerformed
    private void cmdSysFactoryResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSysFactoryResetActionPerformed
        btnSendEcho("sys factoryRESET");
    }//GEN-LAST:event_cmdSysFactoryResetActionPerformed

    private void cmdSysGetVerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSysGetVerActionPerformed
        btnSendEcho("sys get ver");
    }//GEN-LAST:event_cmdSysGetVerActionPerformed

    private void cmdSysGetHwEuiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSysGetHwEuiActionPerformed
        btnSendEcho("sys get hweui");
    }//GEN-LAST:event_cmdSysGetHwEuiActionPerformed

    private void cmdMacTXActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacTXActionPerformed
        btnSendEcho("mac tx " + TxConfirmed.getSelectedItem() + " " + MacTxPort.getText().trim() + " " + MacTxData.getText().trim());
    }//GEN-LAST:event_cmdMacTXActionPerformed

    private void cmdMacjoinABPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacjoinABPActionPerformed
        btnSendEcho("mac join abp");
    }//GEN-LAST:event_cmdMacjoinABPActionPerformed

    private void cmdMacJoinOTAAActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacJoinOTAAActionPerformed
        btnSendEcho("mac join otaa");
    }//GEN-LAST:event_cmdMacJoinOTAAActionPerformed

    private void cmdMacSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSaveActionPerformed
        btnSendEcho("mac save");
    }//GEN-LAST:event_cmdMacSaveActionPerformed

    private void cmdMacSetDevAddrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetDevAddrActionPerformed
        btnSendEcho("mac set devaddr " + DevAddr.getText().trim());
    }//GEN-LAST:event_cmdMacSetDevAddrActionPerformed

    private void cmdMacSetDevEuiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetDevEuiActionPerformed
        btnSendEcho("mac set deveui " + DevEUI.getText().trim());
    }//GEN-LAST:event_cmdMacSetDevEuiActionPerformed

    private void cmdMacSetAppEuiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetAppEuiActionPerformed
        btnSendEcho("mac set appeui " + AppEUI.getText().trim());
    }//GEN-LAST:event_cmdMacSetAppEuiActionPerformed

    private void cmdMacSetNwkSKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetNwkSKeyActionPerformed
        btnSendEcho("mac set nwkskey " + NwkSKey.getText().trim());
    }//GEN-LAST:event_cmdMacSetNwkSKeyActionPerformed

    private void cmdMacSetAppSKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetAppSKeyActionPerformed
        btnSendEcho("mac set appskey " + AppSKey.getText().trim());
    }//GEN-LAST:event_cmdMacSetAppSKeyActionPerformed

    private void cmdMacSetAppKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetAppKeyActionPerformed
        btnSendEcho("mac set appkey " + AppKey.getText().trim());
    }//GEN-LAST:event_cmdMacSetAppKeyActionPerformed

    private void cmdMacSetPwrIdxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetPwrIdxActionPerformed
        btnSendEcho("mac set pwridx " + MacPower.getText().trim());
    }//GEN-LAST:event_cmdMacSetPwrIdxActionPerformed

    private void cmdMacSetDRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetDRActionPerformed
        btnSendEcho("mac set dr " + MacDR.getText().trim());
    }//GEN-LAST:event_cmdMacSetDRActionPerformed

    private void cmdMacSetAdrOnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetAdrOnActionPerformed
        btnSendEcho("mac set adr on");
    }//GEN-LAST:event_cmdMacSetAdrOnActionPerformed

    private void cmdMacSetAdrOffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacSetAdrOffActionPerformed
        btnSendEcho("mac set adr off");
    }//GEN-LAST:event_cmdMacSetAdrOffActionPerformed

    private void cmdMacGetDevAddrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetDevAddrActionPerformed
        btnSendEcho("mac get devaddr");
    }//GEN-LAST:event_cmdMacGetDevAddrActionPerformed

    private void cmdMacGetDevEuiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetDevEuiActionPerformed
        btnSendEcho("mac get deveui");
    }//GEN-LAST:event_cmdMacGetDevEuiActionPerformed

    private void cmdMacGetAppEuiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetAppEuiActionPerformed
        btnSendEcho("mac get appeui");
    }//GEN-LAST:event_cmdMacGetAppEuiActionPerformed

    private void cmdMacGetDRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetDRActionPerformed
        btnSendEcho("mac get dr");
    }//GEN-LAST:event_cmdMacGetDRActionPerformed

    private void cmdMacGetAdrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetAdrActionPerformed
        btnSendEcho("mac get adr");
    }//GEN-LAST:event_cmdMacGetAdrActionPerformed

    private void cmdMacGetStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetStatusActionPerformed
        btnSendEcho("mac get status");
    }//GEN-LAST:event_cmdMacGetStatusActionPerformed

    private void DevAddrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DevAddrActionPerformed
        cmdMacSetDevAddr.doClick();
    }//GEN-LAST:event_DevAddrActionPerformed

    private void NwkSKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NwkSKeyActionPerformed
        cmdMacSetNwkSKey.doClick();
    }//GEN-LAST:event_NwkSKeyActionPerformed

    private void AppSKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AppSKeyActionPerformed
        cmdMacSetAppSKey.doClick();
    }//GEN-LAST:event_AppSKeyActionPerformed

    private void DevEUIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DevEUIActionPerformed
        cmdMacSetDevEui.doClick();
    }//GEN-LAST:event_DevEUIActionPerformed

    private void AppEUIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AppEUIActionPerformed
        cmdMacSetAppEui.doClick();
    }//GEN-LAST:event_AppEUIActionPerformed

    private void AppKeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AppKeyActionPerformed
        cmdMacSetAppKey.doClick();
    }//GEN-LAST:event_AppKeyActionPerformed

    private void MacDRActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MacDRActionPerformed
        cmdMacSetDR.doClick();
    }//GEN-LAST:event_MacDRActionPerformed

    private void MacPowerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MacPowerActionPerformed
        cmdMacSetPwrIdx.doClick();
    }//GEN-LAST:event_MacPowerActionPerformed

    private void cmdMacGetPwrIdxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdMacGetPwrIdxActionPerformed
        btnSendEcho("mac get pwridx");
    }//GEN-LAST:event_cmdMacGetPwrIdxActionPerformed

    private void MacSFItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MacSFItemStateChanged

    }//GEN-LAST:event_MacSFItemStateChanged

    private void cmdRadiosetRxBwActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadiosetRxBwActionPerformed
        btnSendEcho("radio set rxbw " + RadioRxBandWidth.getText().trim());
    }//GEN-LAST:event_cmdRadiosetRxBwActionPerformed

    private void cmdRadioSetFreqActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadioSetFreqActionPerformed
        btnSendEcho("radio set freq " + RadioFreq.getText().trim());
    }//GEN-LAST:event_cmdRadioSetFreqActionPerformed

    private void cmdRadioGetSFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadioGetSFActionPerformed
         btnSendEcho("radio get sf");
    }//GEN-LAST:event_cmdRadioGetSFActionPerformed

    private void cmdRadioGetBwActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadioGetBwActionPerformed
         btnSendEcho("radio get bw");
    }//GEN-LAST:event_cmdRadioGetBwActionPerformed

    private void cmdRadioGetRxBwActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadioGetRxBwActionPerformed
         btnSendEcho("radio get rxbw");
    }//GEN-LAST:event_cmdRadioGetRxBwActionPerformed

    private void cmdRadioGetFreqActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRadioGetFreqActionPerformed
         btnSendEcho("radio get freq");
    }//GEN-LAST:event_cmdRadioGetFreqActionPerformed

    private void MacSFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MacSFActionPerformed
        if ("comboBoxChanged".equals(evt.getActionCommand())) {
            btnSendEcho("radio set sf " + MacSF.getSelectedItem());
        }
    }//GEN-LAST:event_MacSFActionPerformed

    private void MacBandWidthItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_MacBandWidthItemStateChanged
        
    }//GEN-LAST:event_MacBandWidthItemStateChanged

    private void MacBandWidthActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MacBandWidthActionPerformed
        if ("comboBoxChanged".equals(evt.getActionCommand())) {
            btnSendEcho("radio set bw " + MacBandWidth.getSelectedItem());
        }
    }//GEN-LAST:event_MacBandWidthActionPerformed

    private void TxConfirmedItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_TxConfirmedItemStateChanged
        
    }//GEN-LAST:event_TxConfirmedItemStateChanged

    private void TxConfirmedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_TxConfirmedActionPerformed
        
    }//GEN-LAST:event_TxConfirmedActionPerformed

    private void cmdSetPINGActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSetPINGActionPerformed
        btnSend("AT+PING=\"" + PingIP.getText() + "\"");
    }//GEN-LAST:event_cmdSetPINGActionPerformed

    private void CommandKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_CommandKeyTyped

    }//GEN-LAST:event_CommandKeyTyped

    private void CommandKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_CommandKeyReleased

    }//GEN-LAST:event_CommandKeyReleased

    private void CommandKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_CommandKeyPressed

    }//GEN-LAST:event_CommandKeyPressed

    private void CommandItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_CommandItemStateChanged

    }//GEN-LAST:event_CommandItemStateChanged

    private void CommandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CommandActionPerformed
        //log("CommandActionPerformed " + evt.getActionCommand());
        if ("comboBoxEdited".equals(evt.getActionCommand())) { // Hit Enter
            SendCommand.doClick();
        }
    }//GEN-LAST:event_CommandActionPerformed

    private void DonateSmallActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DonateSmallActionPerformed
        goLink(donate_uri);
    }//GEN-LAST:event_DonateSmallActionPerformed
    
    private void NodeFileSystemInfo() {
        String cmd = "r,u,t=file.fsinfo() print(\"Total : \"..t..\" bytes\\r\\nUsed  : \"..u..\" bytes\\r\\nRemain: \"..r..\" bytes\\r\\n\") r=nil u=nil t=nil";
        LocalEcho = false;
        send(addCRLF(cmd), true);
    }

    private void goLink(URI link) {
        try {
            Desktop.getDesktop().browse(link);

        } catch (IOException ex) {
            Logger.getLogger(ESPlorer.class
                    .getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void DoSnippet(int n) {
        if (Condensed.isSelected()) {
            SendToESP(cmdPrep(Snippets[n]));
        } else {
            SendToESP(Snippets[n]);
        }
    }

    private void CommandsSetNodeMCU() {
        Command.removeAllItems();
        Command.addItem("=node.heap()");
        Command.addItem("=node.chipid()");
        Command.addItem("file.close()");
        Command.addItem("file.remove(\"\")");
        Command.addItem("dofile(\"\")");
        Command.addItem("wifi.setmode(wifi.STATION)");
        Command.addItem("wifi.setmode(wifi.SOFTAP)");
        Command.addItem("wifi.setmode(wifi.STATIONAP)");
        Command.addItem("=wifi.getmode()");
        Command.addItem("wifi.sta.config(\"myssid\",\"mypassword\")");
        Command.addItem("=wifi.sta.getip()");
        Command.addItem("=wifi.ap.getip()");
        Command.addItem("=wifi.sta.getmac()");
        Command.addItem("=wifi.ap.getmac()");
        Command.addItem("=wifi.sta.status()");
        Command.addItem("=tmr.now()");
    }

    private void CommandsSetMicroPython() {
        Command.removeAllItems();
        Command.addItem("import sys; print(sys.version_info)");
    }

    private void CommandsSetAT() {
        Command.removeAllItems();
        Command.addItem("AT");
        Command.addItem("AT+GMR");
        Command.addItem("AT+RST");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        /* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        LAFselection = new HashMap<>();
        prefs = Preferences.userRoot().node(NODEROOT);
        systemLaf = javax.swing.UIManager.getSystemLookAndFeelClassName();
        laf = prefs.get("LAF", "javax.swing.plaf.nimbus.NimbusLookAndFeel");
        try {
            javax.swing.UIManager.setLookAndFeel(laf);
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
        }
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem();
            boolean selected = info.getClassName().equals(laf);
            String system = info.getClassName().equals(UIManager.getSystemLookAndFeelClassName()) ? "(系统) ": "";
            String crossplatform = info.getClassName().equals(UIManager.getCrossPlatformLookAndFeelClassName()) ? "(跨平台)": "";
            menuItem.setText(info.getName() + system + crossplatform);
            menuItem.setSelected(selected);
            menuItem.setActionCommand(info.getClassName());
            LAFselection.put(info.getClassName(), menuItem);

            LOGGER.log(java.util.logging.Level.INFO, selected? "选择":"安装" + "皮肤" + info.getName() + " (" + info.getClassName()+ ")");
        }
        
        //</editor-fold>
        try {
            /* Create and display the form */
            java.awt.EventQueue.invokeLater(() -> {
                new ESPlorer().setVisible(true);
            });

        } catch (Exception ex) {
            java.util.logging.Logger.getLogger(ESPlorer.class
                    .getName()).log(java.util.logging.Level.INFO, null, ex);
        }
    }

    private static HashMap<String, JRadioButtonMenuItem> LAFselection;

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLayeredPane ABPPane;
    private javax.swing.JButton ATE0;
    private javax.swing.JButton ATE1;
    private javax.swing.JPanel AT_Client;
    private javax.swing.JButton AT_GMR;
    private javax.swing.JButton AT_Restart;
    private javax.swing.JPanel AT_Server;
    private javax.swing.JLayeredPane AT_SoftAP;
    private javax.swing.JPanel AT_Station;
    private javax.swing.JLayeredPane ATvXX;
    private javax.swing.JDialog About;
    private javax.swing.JLayeredPane ActivationPane;
    private javax.swing.JScrollPane ActivationScrollPane;
    private javax.swing.JCheckBoxMenuItem AlwaysOnTop;
    private javax.swing.JSlider AnswerDelay;
    private javax.swing.JLabel AnswerDelayLabel;
    private javax.swing.JTextField AppEUI;
    private javax.swing.JTextField AppKey;
    private javax.swing.JLabel AppName;
    private javax.swing.JTextField AppSKey;
    private javax.swing.JLabel Author;
    private javax.swing.JLabel Author1;
    private javax.swing.JCheckBox AutoScroll;
    private javax.swing.JCheckBox AutodetectFirmware;
    private javax.swing.JLayeredPane BasicATcommandsPane;
    private javax.swing.JLabel Busy;
    private javax.swing.JButton ButtonCopy;
    private javax.swing.JButton ButtonCut;
    private javax.swing.JButton ButtonFileClose;
    private javax.swing.JButton ButtonFileNew;
    private javax.swing.JButton ButtonFileOpen;
    private javax.swing.JButton ButtonFileReload;
    private javax.swing.JButton ButtonFileSave;
    private javax.swing.JButton ButtonFileSaveAll;
    private javax.swing.JButton ButtonPaste;
    private javax.swing.JButton ButtonRedo;
    private javax.swing.JButton ButtonSendLine;
    private javax.swing.JButton ButtonSendSelected;
    private javax.swing.JButton ButtonSnippet0;
    private javax.swing.JButton ButtonSnippet1;
    private javax.swing.JButton ButtonSnippet10;
    private javax.swing.JButton ButtonSnippet11;
    private javax.swing.JButton ButtonSnippet12;
    private javax.swing.JButton ButtonSnippet13;
    private javax.swing.JButton ButtonSnippet14;
    private javax.swing.JButton ButtonSnippet15;
    private javax.swing.JButton ButtonSnippet2;
    private javax.swing.JButton ButtonSnippet3;
    private javax.swing.JButton ButtonSnippet4;
    private javax.swing.JButton ButtonSnippet5;
    private javax.swing.JButton ButtonSnippet6;
    private javax.swing.JButton ButtonSnippet7;
    private javax.swing.JButton ButtonSnippet8;
    private javax.swing.JButton ButtonSnippet9;
    private javax.swing.JButton ButtonUndo;
    private javax.swing.JCheckBox CR;
    private javax.swing.JComboBox<String> Command;
    private javax.swing.JCheckBox CommandEcho;
    private javax.swing.JLayeredPane CommandsMicroPython;
    private javax.swing.JLayeredPane CommandsNodeMCU;
    private javax.swing.JCheckBox Condensed;
    private javax.swing.JPopupMenu ContextMenuESPFileLUA;
    private javax.swing.JPopupMenu ContextMenuEditor;
    private javax.swing.JPopupMenu ContextMenuFileManager;
    private javax.swing.JPopupMenu ContextMenuLog;
    private javax.swing.JPopupMenu ContextMenuTerminal;
    private javax.swing.JTextField CustomPortName;
    private javax.swing.JComboBox DHCP;
    private javax.swing.JComboBox DHCPmode;
    private javax.swing.JSlider Delay;
    private javax.swing.JLabel DelayLabel;
    private javax.swing.JTextField DevAddr;
    private javax.swing.JTextField DevEUI;
    private javax.swing.JButton Donate;
    private javax.swing.JButton DonateSmall;
    private javax.swing.JCheckBox DumbMode;
    private javax.swing.JCheckBox EOL;
    private javax.swing.JCheckBox EditorOnlyCheckBox;
    private javax.swing.JPopupMenu.Separator EditorSeparator;
    private javax.swing.JPopupMenu.Separator EditorSeparator1;
    private javax.swing.JPopupMenu.Separator EditorSeparator2;
    private javax.swing.JComboBox EditorTheme;
    private javax.swing.JLabel EditorThemeLabel;
    private javax.swing.JButton FileAsButton1;
    private javax.swing.JCheckBox FileAutoRun;
    private javax.swing.JCheckBox FileAutoSaveDisk;
    private javax.swing.JCheckBox FileAutoSaveESP;
    private javax.swing.JButton FileCompile;
    private javax.swing.JButton FileCompileDoLC;
    private javax.swing.JButton FileDo;
    private javax.swing.JButton FileDo1;
    private javax.swing.JButton FileFormat;
    private javax.swing.JLayeredPane FileLayeredPane;
    private javax.swing.JButton FileListReload;
    private javax.swing.JScrollPane FileManagerScrollPane;
    private javax.swing.JLayeredPane FileManagersLayer;
    private javax.swing.JLabel FilePathLabel;
    private javax.swing.JTextField FileRename;
    private javax.swing.JLabel FileRenameLabel;
    private javax.swing.JLayeredPane FileRenamePanel;
    private javax.swing.JButton FileSaveCompileDoLC;
    private javax.swing.JToggleButton FileSaveESP;
    private javax.swing.JToggleButton FileSendESP;
    private javax.swing.JButton FileSystemInfo;
    private javax.swing.JButton FileUploadBin;
    private javax.swing.JTabbedPane FilesTabbedPane;
    private javax.swing.JToolBar FilesToolBar;
    private javax.swing.JButton FilesUpload;
    private javax.swing.ButtonGroup Firmware;
    private javax.swing.JButton GSLP;
    private javax.swing.JButton HomePage;
    private javax.swing.JSplitPane HorizontSplit;
    private javax.swing.JLayeredPane LEDPanel;
    private javax.swing.JCheckBox LF;
    private javax.swing.JLayeredPane LeftBasePane;
    private javax.swing.JLayeredPane LeftExtraButtons;
    private javax.swing.JLayeredPane LeftMainButtons;
    private javax.swing.JLayeredPane LeftSnippetsPane;
    private javax.swing.JTabbedPane LeftTab;
    private javax.swing.JSlider LineDelay;
    private javax.swing.JLabel LineDelayLabel;
    private javax.swing.JLayeredPane LoRaMAC;
    private javax.swing.JTextArea Log;
    private javax.swing.JTextField LogMaxSize;
    private javax.swing.JPopupMenu.Separator LogSeparator;
    private javax.swing.JFormattedTextField MAC;
    private javax.swing.JFormattedTextField MAC1;
    private javax.swing.ButtonGroup MUXGroup;
    private javax.swing.JComboBox<String> MacBandWidth;
    private javax.swing.JLayeredPane MacCommon;
    private javax.swing.JTextField MacDR;
    private javax.swing.JScrollPane MacPane;
    private javax.swing.JTextField MacPower;
    private javax.swing.JComboBox<String> MacSF;
    private javax.swing.JTextField MacTxData;
    private javax.swing.JTextField MacTxPort;
    private javax.swing.JMenuBar MainMenuBar;
    private javax.swing.JMenu MenuESP;
    private javax.swing.JMenu MenuEdit;
    private javax.swing.JMenu MenuFile;
    private javax.swing.JMenu MenuHelp;
    private javax.swing.JMenuItem MenuItemESPFileDelete;
    private javax.swing.JMenuItem MenuItemESPFileDo;
    private javax.swing.JMenuItem MenuItemESPFormat;
    private javax.swing.JMenuItem MenuItemESPReset;
    private javax.swing.JMenuItem MenuItemEditCopy;
    private javax.swing.JMenuItem MenuItemEditCut;
    private javax.swing.JMenuItem MenuItemEditPaste;
    private javax.swing.JMenuItem MenuItemEditRedo;
    private javax.swing.JMenuItem MenuItemEditSendLine;
    private javax.swing.JMenuItem MenuItemEditSendSelected;
    private javax.swing.JMenuItem MenuItemEditUndo;
    private javax.swing.JMenuItem MenuItemEditorCopy;
    private javax.swing.JMenuItem MenuItemEditorCut;
    private javax.swing.JMenuItem MenuItemEditorFontDec;
    private javax.swing.JMenuItem MenuItemEditorFontInc;
    private javax.swing.JMenuItem MenuItemEditorPaste;
    private javax.swing.JMenuItem MenuItemEditorRedo;
    private javax.swing.JMenuItem MenuItemEditorSendLine;
    private javax.swing.JMenuItem MenuItemEditorSendSelected;
    private javax.swing.JMenuItem MenuItemEditorUndo;
    private javax.swing.JMenuItem MenuItemFileClose;
    private javax.swing.JMenuItem MenuItemFileDo;
    private javax.swing.JMenuItem MenuItemFileExit;
    private javax.swing.JMenuItem MenuItemFileNew;
    private javax.swing.JMenuItem MenuItemFileOpen;
    private javax.swing.JMenuItem MenuItemFileReload;
    private javax.swing.JMenuItem MenuItemFileRemoveESP;
    private javax.swing.JMenuItem MenuItemFileSave;
    private javax.swing.JMenuItem MenuItemFileSaveAll;
    private javax.swing.JMenuItem MenuItemFileSaveAs;
    private javax.swing.JMenuItem MenuItemFileSaveESP;
    private javax.swing.JMenuItem MenuItemFileSendESP;
    private javax.swing.JMenuItem MenuItemHelpAbout;
    private javax.swing.JMenuItem MenuItemLinksBuyDevBoard;
    private javax.swing.JMenuItem MenuItemLinksBuyESD12;
    private javax.swing.JMenuItem MenuItemLinksBuyESP8266;
    private javax.swing.JMenuItem MenuItemLinksBuyOther;
    private javax.swing.JMenuItem MenuItemLinksDonate;
    private javax.swing.JMenuItem MenuItemLinksESPlorerForumEn;
    private javax.swing.JMenuItem MenuItemLinksESPlorerForumRu;
    private javax.swing.JMenuItem MenuItemLinksESPlorerHome;
    private javax.swing.JMenuItem MenuItemLinksESPlorerLatest;
    private javax.swing.JMenuItem MenuItemLinksESPlorerSource;
    private javax.swing.JMenuItem MenuItemLinksIoTmanager;
    private javax.swing.JMenuItem MenuItemLinksMicroPythonDoc;
    private javax.swing.JMenuItem MenuItemLinksNodeMCUdoc;
    private javax.swing.JMenuItem MenuItemLogClear;
    private javax.swing.JMenuItem MenuItemLogClose;
    private javax.swing.JMenuItem MenuItemLogFontDec;
    private javax.swing.JMenuItem MenuItemLogFontInc;
    private javax.swing.JMenuItem MenuItemTerminalClear;
    private javax.swing.JMenuItem MenuItemTerminalCopy;
    private javax.swing.JMenuItem MenuItemTerminalFontDec;
    private javax.swing.JMenuItem MenuItemTerminalFontInc;
    private javax.swing.JMenuItem MenuItemTerminalFormat;
    private javax.swing.JMenuItem MenuItemTerminalReset;
    private javax.swing.JMenuItem MenuItemViewClearLog;
    private javax.swing.JMenuItem MenuItemViewClearTerminal;
    private javax.swing.JCheckBoxMenuItem MenuItemViewDonate;
    private javax.swing.JMenuItem MenuItemViewEditorFontDec;
    private javax.swing.JMenuItem MenuItemViewEditorFontInc;
    private javax.swing.JCheckBoxMenuItem MenuItemViewEditorOnly;
    private javax.swing.JCheckBoxMenuItem MenuItemViewFileManager;
    private javax.swing.JMenuItem MenuItemViewFontDefault;
    private javax.swing.JCheckBoxMenuItem MenuItemViewLeftExtra;
    private javax.swing.JCheckBoxMenuItem MenuItemViewLog;
    private javax.swing.JMenuItem MenuItemViewLogFontDec;
    private javax.swing.JMenuItem MenuItemViewLogFontInc;
    private javax.swing.JCheckBoxMenuItem MenuItemViewRightExtra;
    private javax.swing.JCheckBoxMenuItem MenuItemViewSnippets;
    private javax.swing.JMenuItem MenuItemViewTermFontDec;
    private javax.swing.JMenuItem MenuItemViewTermFontInc;
    private javax.swing.JCheckBoxMenuItem MenuItemViewTerminalOnly;
    private javax.swing.JCheckBoxMenuItem MenuItemViewToolbar;
    private javax.swing.JMenu MenuLinks;
    private javax.swing.JMenu MenuView;
    private javax.swing.JLayeredPane MicroPythonCommandsGPIO;
    private javax.swing.JTabbedPane MicroPythonCommandsTab;
    private javax.swing.JLayeredPane MicroPythonCommandsWiFi;
    private javax.swing.JButton MicroPythonGPIO0;
    private javax.swing.JButton MicroPythonGPIO0_0;
    private javax.swing.JButton MicroPythonGPIO0_1;
    private javax.swing.JButton MicroPythonGPIO10;
    private javax.swing.JButton MicroPythonGPIO10_0;
    private javax.swing.JButton MicroPythonGPIO10_1;
    private javax.swing.JButton MicroPythonGPIO12;
    private javax.swing.JButton MicroPythonGPIO12_0;
    private javax.swing.JButton MicroPythonGPIO12_1;
    private javax.swing.JButton MicroPythonGPIO13;
    private javax.swing.JButton MicroPythonGPIO13_0;
    private javax.swing.JButton MicroPythonGPIO13_1;
    private javax.swing.JButton MicroPythonGPIO14;
    private javax.swing.JButton MicroPythonGPIO14_0;
    private javax.swing.JButton MicroPythonGPIO14_1;
    private javax.swing.JButton MicroPythonGPIO15;
    private javax.swing.JButton MicroPythonGPIO15_0;
    private javax.swing.JButton MicroPythonGPIO15_1;
    private javax.swing.JButton MicroPythonGPIO16;
    private javax.swing.JButton MicroPythonGPIO16_0;
    private javax.swing.JButton MicroPythonGPIO16_1;
    private javax.swing.JButton MicroPythonGPIO2;
    private javax.swing.JButton MicroPythonGPIO2_0;
    private javax.swing.JButton MicroPythonGPIO2_1;
    private javax.swing.JButton MicroPythonGPIO4;
    private javax.swing.JButton MicroPythonGPIO4_0;
    private javax.swing.JButton MicroPythonGPIO4_1;
    private javax.swing.JButton MicroPythonGPIO5;
    private javax.swing.JButton MicroPythonGPIO5_0;
    private javax.swing.JButton MicroPythonGPIO5_1;
    private javax.swing.JButton MicroPythonGPIO9;
    private javax.swing.JButton MicroPythonGPIO9_0;
    private javax.swing.JButton MicroPythonGPIO9_1;
    private javax.swing.JTextField MicroPythonPASS;
    private javax.swing.JTextField MicroPythonRemoteData;
    private javax.swing.JTextField MicroPythonRemoteHost;
    private javax.swing.JTextField MicroPythonRemotePort;
    private javax.swing.JTextField MicroPythonSSID;
    private javax.swing.JButton NodeChipID;
    private javax.swing.JLayeredPane NodeFileManagerPane;
    private javax.swing.JButton NodeFlashID;
    private javax.swing.JButton NodeHeap;
    private javax.swing.JButton NodeInfo;
    private javax.swing.JPanel NodeMCU;
    private javax.swing.JLayeredPane NodeMCUCommands;
    private javax.swing.JLayeredPane NodeMCUSettings;
    private javax.swing.JLayeredPane NodeMCUSnippets;
    private javax.swing.JButton NodeReset;
    private javax.swing.JTextField NwkSKey;
    private javax.swing.JLayeredPane OTAAPane;
    private javax.swing.JToggleButton Open;
    private javax.swing.JRadioButton OptionMicroPython;
    private javax.swing.JRadioButton OptionNodeMCU;
    private javax.swing.JLayeredPane OptionsFileSendMode;
    private javax.swing.JLayeredPane OptionsFirmware;
    private javax.swing.JLayeredPane OptionsOther;
    private javax.swing.JTextField PASS;
    private javax.swing.JTextField PASSsoftAP;
    private javax.swing.JTextField PingIP;
    private javax.swing.JComboBox<String> Port;
    private javax.swing.JLabel PortCTS;
    private javax.swing.JToggleButton PortDTR;
    private javax.swing.JLabel PortOpenLabel;
    private javax.swing.JToggleButton PortRTS;
    private javax.swing.JProgressBar ProgressBar;
    private javax.swing.JButton PyFileAsButton1;
    private javax.swing.JLayeredPane PyFileManagerPane;
    private javax.swing.JButton PyListDir;
    private javax.swing.JLayeredPane RN2483;
    private javax.swing.JTabbedPane RN2483jTab;
    private javax.swing.JTextField RadioFreq;
    private javax.swing.JLayeredPane RadioPane;
    private javax.swing.JTextField RadioRxBandWidth;
    private javax.swing.JButton ReScan;
    private javax.swing.JLayeredPane RightBasePane;
    private javax.swing.JLayeredPane RightBigPane;
    private javax.swing.JLayeredPane RightBottomPane;
    private javax.swing.JLayeredPane RightExtraButtons;
    private javax.swing.JSplitPane RightFilesSplitPane;
    private javax.swing.JLayeredPane RightSnippetsPane;
    private javax.swing.JSplitPane RightSplitPane;
    private javax.swing.JTextField SSID;
    private javax.swing.JTextField SSIDsoftAP;
    private javax.swing.JScrollPane ScrollLog;
    private javax.swing.JButton SendCommand;
    private javax.swing.JLayeredPane SendUnconfirmed;
    private javax.swing.JComboBox ServerMode;
    private javax.swing.JTextField ServerPort;
    private javax.swing.JTextField ServerTimeout;
    private javax.swing.JCheckBoxMenuItem ShowFileManager;
    private javax.swing.JButton SnippetCancelEdit;
    private javax.swing.JButton SnippetEdit0;
    private javax.swing.JButton SnippetEdit1;
    private javax.swing.JButton SnippetEdit10;
    private javax.swing.JButton SnippetEdit11;
    private javax.swing.JButton SnippetEdit12;
    private javax.swing.JButton SnippetEdit13;
    private javax.swing.JButton SnippetEdit14;
    private javax.swing.JButton SnippetEdit15;
    private javax.swing.JButton SnippetEdit2;
    private javax.swing.JButton SnippetEdit3;
    private javax.swing.JButton SnippetEdit4;
    private javax.swing.JButton SnippetEdit5;
    private javax.swing.JButton SnippetEdit6;
    private javax.swing.JButton SnippetEdit7;
    private javax.swing.JButton SnippetEdit8;
    private javax.swing.JButton SnippetEdit9;
    private javax.swing.JTextField SnippetName;
    private javax.swing.JButton SnippetRun;
    private javax.swing.JButton SnippetSave;
    private org.fife.ui.rtextarea.RTextScrollPane SnippetScrollPane;
    private org.fife.ui.rsyntaxtextarea.RSyntaxTextArea SnippetText;
    private javax.swing.JLayeredPane SnippetTopPane;
    private javax.swing.JLabel SnippetsBusy;
    private javax.swing.JComboBox Speed;
    private javax.swing.JLayeredPane SriptsTab;
    private javax.swing.JTextField StationIP;
    private javax.swing.JLayeredPane TCPServerBottomPane;
    private javax.swing.Box.Filler TCPServerTopFiller;
    private javax.swing.JLayeredPane TCP_common;
    private javax.swing.JLayeredPane TCPclientBottomPane;
    private javax.swing.JTabbedPane TabAT;
    public static org.fife.ui.rsyntaxtextarea.RSyntaxTextArea Terminal;
    private javax.swing.JLayeredPane TerminalLogPane;
    private javax.swing.JTextField TerminalMaxSize;
    private javax.swing.JCheckBox TerminalOnlyCheckBox;
    private org.fife.ui.rtextarea.RTextScrollPane TerminalPane;
    private javax.swing.JPopupMenu.Separator TerminalSeparator1;
    private javax.swing.JPopupMenu.Separator TerminalSeparator2;
    private javax.swing.JPopupMenu.Separator TerminalSeparator3;
    private org.fife.ui.rsyntaxtextarea.RSyntaxTextArea TextEditor;
    private org.fife.ui.rtextarea.RTextScrollPane TextScroll;
    private javax.swing.JTabbedPane TextTab;
    private javax.swing.JComboBox TimerNumber;
    private javax.swing.Box.Filler TopWiFiAPFiller;
    private javax.swing.Box.Filler TopWiFiStaFiller;
    private javax.swing.Box.Filler TopWiFiStaFiller1;
    private javax.swing.JCheckBox TurboMode;
    private javax.swing.JComboBox<String> TxConfirmed;
    private javax.swing.JLayeredPane UDP;
    private javax.swing.JButton UPDATE;
    private javax.swing.JCheckBox UseCustomPortName;
    private javax.swing.JCheckBox UseExternalEditor;
    private javax.swing.JLabel Version;
    private javax.swing.JLayeredPane WiFiStationPane;
    private javax.swing.JLayeredPane WiFi_common;
    private javax.swing.JLayeredPane WiFisoftAPPane;
    private javax.swing.ButtonGroup buttonGroupLF;
    private javax.swing.JComboBox channel;
    private javax.swing.JButton cmdAT;
    private javax.swing.JButton cmdCIPSEND;
    private javax.swing.JButton cmdCIPSENDinteractive;
    private javax.swing.JButton cmdGetCIFSR;
    private javax.swing.JButton cmdGetCIPAP;
    private javax.swing.JButton cmdGetCIPAPMAC;
    private javax.swing.JButton cmdGetCIPMODE;
    private javax.swing.JButton cmdGetCIPMUX;
    private javax.swing.JButton cmdGetCIPSTA;
    private javax.swing.JButton cmdGetCIPSTAMAC;
    private javax.swing.JButton cmdGetCIPSTART;
    private javax.swing.JButton cmdGetCIPSTATUS;
    private javax.swing.JButton cmdGetCIPSTO;
    private javax.swing.JButton cmdGetCWJAP;
    private javax.swing.JButton cmdGetCWLIF;
    private javax.swing.JButton cmdGetCWMODE;
    private javax.swing.JButton cmdGetCWSAP;
    private javax.swing.JButton cmdGetHelpCWMODE;
    private javax.swing.JButton cmdListFiles;
    private javax.swing.JButton cmdMacGetAdr;
    private javax.swing.JButton cmdMacGetAppEui;
    private javax.swing.JButton cmdMacGetDR;
    private javax.swing.JButton cmdMacGetDevAddr;
    private javax.swing.JButton cmdMacGetDevEui;
    private javax.swing.JButton cmdMacGetPwrIdx;
    private javax.swing.JButton cmdMacGetStatus;
    private javax.swing.JButton cmdMacJoinOTAA;
    private javax.swing.JButton cmdMacSave;
    private javax.swing.JButton cmdMacSetAdrOff;
    private javax.swing.JButton cmdMacSetAdrOn;
    private javax.swing.JButton cmdMacSetAppEui;
    private javax.swing.JButton cmdMacSetAppKey;
    private javax.swing.JButton cmdMacSetAppSKey;
    private javax.swing.JButton cmdMacSetDR;
    private javax.swing.JButton cmdMacSetDevAddr;
    private javax.swing.JButton cmdMacSetDevEui;
    private javax.swing.JButton cmdMacSetNwkSKey;
    private javax.swing.JButton cmdMacSetPwrIdx;
    private javax.swing.JButton cmdMacTX;
    private javax.swing.JButton cmdMacjoinABP;
    private javax.swing.JButton cmdMicroPythonScan;
    private javax.swing.JButton cmdMicroPythonSendToHost;
    private javax.swing.JButton cmdMicroPythonStaConnect;
    private javax.swing.JButton cmdNodeChipID;
    private javax.swing.JButton cmdNodeHeap;
    private javax.swing.JButton cmdNodeRestart;
    private javax.swing.JButton cmdNodeSleep;
    private javax.swing.JButton cmdRadioGetBw;
    private javax.swing.JButton cmdRadioGetFreq;
    private javax.swing.JButton cmdRadioGetRxBw;
    private javax.swing.JButton cmdRadioGetSF;
    private javax.swing.JButton cmdRadioSetFreq;
    private javax.swing.JButton cmdRadiosetRxBw;
    private javax.swing.JButton cmdSetCIPAP;
    private javax.swing.JButton cmdSetCIPAPMAC;
    private javax.swing.JButton cmdSetCIPCLOSE;
    private javax.swing.JButton cmdSetCIPMODE0;
    private javax.swing.JButton cmdSetCIPMODE1;
    private javax.swing.JButton cmdSetCIPMUX0;
    private javax.swing.JButton cmdSetCIPMUX1;
    private javax.swing.JButton cmdSetCIPSERVER;
    private javax.swing.JButton cmdSetCIPSTA;
    private javax.swing.JButton cmdSetCIPSTAMAC;
    private javax.swing.JButton cmdSetCIPSTART;
    private javax.swing.JButton cmdSetCIPSTO;
    private javax.swing.JButton cmdSetCWDHCP;
    private javax.swing.JButton cmdSetCWJAP;
    private javax.swing.JButton cmdSetCWLAP;
    private javax.swing.JButton cmdSetCWMODE1;
    private javax.swing.JButton cmdSetCWMODE2;
    private javax.swing.JButton cmdSetCWMODE3;
    private javax.swing.JButton cmdSetCWQAP;
    private javax.swing.JButton cmdSetCWSAP;
    private javax.swing.JButton cmdSetPING;
    private javax.swing.JButton cmdSysFactoryReset;
    private javax.swing.JButton cmdSysGetHwEui;
    private javax.swing.JButton cmdSysGetVer;
    private javax.swing.JButton cmdSysReset;
    private javax.swing.JButton cmdTimerStop;
    private javax.swing.JPanel common;
    private javax.swing.JComboBox conn_id;
    private javax.swing.JTextArea data;
    private javax.swing.JComboBox encryption;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JLayeredPane jLayeredPane1;
    private javax.swing.JLayeredPane jLayeredPane2;
    private javax.swing.JLayeredPane jLayeredPane3;
    private javax.swing.JLayeredPane jLayeredPane4;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem7;
    private javax.swing.JScrollPane jScrollData;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator10;
    private javax.swing.JPopupMenu.Separator jSeparator11;
    private javax.swing.JPopupMenu.Separator jSeparator12;
    private javax.swing.JPopupMenu.Separator jSeparator13;
    private javax.swing.JPopupMenu.Separator jSeparator15;
    private javax.swing.JPopupMenu.Separator jSeparator16;
    private javax.swing.JPopupMenu.Separator jSeparator17;
    private javax.swing.JPopupMenu.Separator jSeparator18;
    private javax.swing.JPopupMenu.Separator jSeparator19;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator20;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JPopupMenu.Separator jSeparator4;
    private javax.swing.JPopupMenu.Separator jSeparator5;
    private javax.swing.JToolBar.Separator jSeparator6;
    private javax.swing.JPopupMenu.Separator jSeparator7;
    private javax.swing.JToolBar.Separator jSeparator8;
    private javax.swing.JPopupMenu.Separator jSeparator9;
    private javax.swing.JPopupMenu.Separator jSeparatorFileMenu;
    private javax.swing.JRadioButton multi;
    private javax.swing.JComboBox protocol;
    private javax.swing.JTextField remote_address;
    private javax.swing.JTextField remote_port;
    private javax.swing.JRadioButton single;
    private javax.swing.JTextField softAPIP;
    private javax.swing.JTextField udp_local_port;
    private javax.swing.JTextField udp_mode;
    // End of variables declaration//GEN-END:variables

    // Variables
    private static final boolean DEBUG = false;
    /* Files tab start */
    private ArrayList<javax.swing.JLayeredPane> FileLayeredPane1;
    private ArrayList<org.fife.ui.rsyntaxtextarea.RSyntaxTextArea> TextEditor1;
    private ArrayList<org.fife.ui.rtextarea.RTextScrollPane> TextScroll1;
    private ArrayList<javax.swing.GroupLayout> FileLayeredPaneLayout1;
    private ArrayList<CompletionProvider> provider;
    private ArrayList<AutoCompletion> ac;
    private ArrayList<File> iFile; // for files in tab
    private ArrayList<File> mFile; // for multifile op
    private ArrayList<Boolean> FileChanged;
    private ArrayList<javax.swing.JButton> FileAsButton;
    private ArrayList<javax.swing.JButton> PyFileAsButton;
    private ArrayList<javax.swing.JPopupMenu> FilePopupMenu;
    private ArrayList<javax.swing.JMenuItem> FilePopupMenuItem;
    private int iTab = 0; // tab index
    private int mFileIndex = -1; // multifile index
    private String UploadFileName = "";
    /* Files tab end */
    public int nSpeed = 9600;
    public static final Logger LOGGER = Logger.getLogger(ESPlorer.class.getName());
    int save; // editor var
    String FileName = "script"; // without ext
    String DownloadedFileName = "";
    String NewFile = "New";
    int FileCount = 0;
    String workDir = "";
    JFileChooser chooser;
    static final String[] EXTENSION_LUA = new String[]{"lua", "lc"};
    static final String[] EXTENSION_PY = new String[]{"py", "pyc"};
    static final String[] EXTENSION_ALL = new String[]{"*"};
    static final FileNameExtensionFilter FILTER_LUA = new FileNameExtensionFilter("LUA files (*.lua, *.lc)", EXTENSION_LUA);
    static final FileNameExtensionFilter FILTER_PYTHON = new FileNameExtensionFilter("Python files (*.py, *.pyc)", EXTENSION_PY);
    static final FileNameExtensionFilter FILTER_ALL = new FileNameExtensionFilter("All files (*.*)", EXTENSION_ALL);
    FileInputStream fis = null;
    FileOutputStream fos = null;
    InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    BufferedReader br = null;
    BufferedWriter bw = null;
    public static int j = 0;
    public static int pyLevel = 0;
    public static boolean sendPending = false;
    public static String s[];
    public ActionListener taskPerformer;
    public ActionListener watchDog;
    public ActionListener checker;
    public ActionListener taskSleep;
    public Timer timer;
    public Timer timeout;
    public Timer sleep;
    public Timer openTimeout;
    public Color color;
    public Color themeTextBackground;
    public static String rcvBuf = "";
    public static String rx_data = "";
    public static String tx_data = "";
    public static byte[] rx_byte;
    public static byte[] tx_byte;
    // downloader
    public int packets = 0;
    public String rcvFile = "";
    public ArrayList<String> rcvPackets;
    public ArrayList<byte[]> sendPackets;
    public ArrayList<Boolean> sendPacketsCRC;
    public ArrayList<String> PacketsData;
    public ArrayList<Integer> PacketsSize;
    public ArrayList<Integer> PacketsCRC;
    public ArrayList<Integer> PacketsNum;
    public byte[] PacketsByte;
    public final int SendPacketSize = 250;
    public static String DownloadCommand;
    // downloader end
    public static int req = 0;
    public static boolean busyIcon = false;
    public URI donate_uri;
    public URI homepage_uri;
    public URI micropython_doc;
    public URI api_en_uri;
    public URI iot_manager;
    public URI changelog_uri;
    public URI nodemcu_download_latest_uri;
    public URI nodemcu_download_dev_uri;
    public URI flasher_uri;
    public URI buy_nodeMCU;
    public URI buy_esp8266;
    public URI buy_esd12;
    public URI buy_other;
    public URI esp8266com_uri;
    public URI esp8266ru_uri;
    public URI esplorer_home;
    public URI esplorer_latest;
    public URI esplorer_source;
    private static int LogMax = 10 * 1024;
    private static int TerminalMax = 100 * 1024;
    private long startTime = System.currentTimeMillis();
    private static final float TERMINAL_FONT_SIZE_DEFAULT = 16f;
    private static final float TERMINAL_FONT_SIZE_MAX = 40f;
    private static final float TERMINAL_FONT_SIZE_MIN = 5f;
    private static final float EDITOR_FONT_SIZE_DEFAULT = 13f;
    private static final float EDITOR_FONT_SIZE_MAX = 40f;
    private static final float EDITOR_FONT_SIZE_MIN = 8f;
    private static final float LOG_FONT_SIZE_DEFAULT = 10f;
    private static final float LOG_FONT_SIZE_MAX = 40f;
    private static final float LOG_FONT_SIZE_MIN = 5f;
    /*  Prefs */
    private static final String NODEROOT = "/com/esp8266.ru/ESPlorer/config";
    private static final String SERIAL_PORT = "serial_port";
    private static final String SERIAL_BAUD = "serial_baud";
    private static final String PATH = "path";
    private static final String FIRMWARE = "firmware";
    private static final String FILE_AUTO_SAVE_DISK = "file_auto_save_disk";
    private static final String FILE_AUTO_SAVE_ESP = "file_auto_save_esp";
    private static final String FILE_AUTO_RUN = "file_auto_run";
    private static final String COLOR_THEME = "color_theme";
    private static final String DELAY = "delay";
    private static final String TIMEOUT = "timeout";
    private static final String DUMB_MODE = "dumb_mode";
    private static final String TURBO_MODE = "turbo_mode";
    private static final String LINE_DELAY = "line_delay";
    private static final String TERMINAL_FONT_SIZE = "terminal_font_size";
    private static final String EDITOR_FONT_SIZE = "editor_font_size";
    private static final String LOG_FONT_SIZE = "log_font_size";
    private static final String LOG_MAX_SIZE = "log_max_size";
    private static final String TERMINAL_MAX_SIZE = "terminal_max_size";

    // v0.2
    private static final String AUTO_SCROLL = "auto_scroll";
    private static final String SHOW_LOG = "show_log";
    private static final String SHOW_TOOLBAR = "show_toolbar";
    private static final String SHOW_EXTRA_LEFT = "show_extra_left";
    private static final String SHOW_EXTRA_RIGHT = "show_extra_right";
    private static final String SHOW_SNIP_RIGHT = "show_snip_right";
    private static final String SHOW_FM_RIGHT = "show_fm_right";
    private static final String USE_CUSTOM_PORT = "use_custom_port";
    private static final String CUSTOM_PORT_NAME = "custom_port_name";
    private static final String LOG_DIV = "log_div";
    private static final String FM_DIV = "fm_div";
    private static final String PORT_RTS = "port_rts";
    private static final String PORT_DTR = "port_dtr";
    private static final String USE_EXT_EDITOR = "use_ext_editor";
    private static final String SHOW_DONATE = "show_donate";
    private static final String SHOW_EOL = "show_eol";
    private static final String WIN_X = "win_x";
    private static final String WIN_Y = "win_y";
    private static final String WIN_H = "win_h";
    private static final String WIN_W = "win_w";
    private static final String CONDENSED = "condensed";
    private static final String AUTODETECT = "autodetect_firmware";
    private static final String COMMAND_ECHO = "command_echo";
    /*  Prefs end */

 /* Snippets */
    private static String[] Snippets = new String[16];
    private ArrayList<JButton> snippetButtons = new ArrayList<>();
    private static int iSnippets = 0;

    private static final int portMask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS;
    private static javax.swing.ImageIcon LED_GREY;
    private static javax.swing.ImageIcon LED_GREEN;
    private static javax.swing.ImageIcon LED_RED;
    private static javax.swing.ImageIcon LED_BLUE;

    private static final int FIRMWARE_NODEMCU = 0;
    private static final int FIRMWARE_MPYTHON = 1;
    private static final int FIRMWARE_AT = 2;

    private static boolean LocalEcho = true;

    public void inc_j() {
        ++j;
    }

    public void j0() {
        j = 0;
    }

    public void inc_pyLevel() {
        ++pyLevel;
    }

    public void dec_pyLevel() {
        --pyLevel;
    }

    public void set_pyLevel(int newValue) {
        pyLevel = newValue;
    }

    public void pyLevel0() {
        pyLevel = 0;
    }

    public void PortFinder() {
        int i;
        Port.removeAllItems();
        if (UseCustomPortName.isSelected()) {
            Port.addItem(CustomPortName.getText().trim());
            Port.setSelectedIndex(Port.getItemCount() - 1);
            Port.setEnabled(false);
            Speed.setSelectedIndex(prefs.getInt(SERIAL_BAUD, 3));
            log("使用自定义端口名称· " + CustomPortName.getText());
            return;
        }
        log("扫描系统...");
        String[] portNames = SerialPortList.getPortNames();
        //  System.out.println(portNames[i]);
        if (portNames.length < 1) {
            log("找不到任何串行端口。请连接设备并重新扫描");
        } else {
            if (prefs.get(SERIAL_PORT, null) == null) {
                prefs.put(SERIAL_PORT, portNames[0]);
            }
            String lastPort = prefs.get(SERIAL_PORT, null);
            int port = 0;
            for (i = 0; i < portNames.length; i++) {
                Port.addItem(portNames[i]);
                if (portNames[i].equals(lastPort)) {
                    port = i;
                    log("找到最近保存的串行端口" + portNames[i]);
                } else {
                    log("找到 " + portNames[i]);
                }
            }
            Port.setSelectedIndex(port);
            Speed.setSelectedIndex(prefs.getInt(SERIAL_BAUD, 3));
        }
        log("扫描完成");
    }

    public void log(String l) {
        String log = Log.getText();
        Document doc = Log.getDocument();
        LOGGER.info(l);
        if (log.length() > LogMax) {
            try {
                doc.remove(0, 1024);
            } catch (BadLocationException e) {
            }
        }
        try {
            doc.insertString(doc.getLength(), "\r\n" + l, null);
        } catch (BadLocationException e) {
        }
        Log.setCaretPosition(Log.getText().length());
    }

    public void log(String l, boolean d) {
        if (d) {
            log(l);
        }
    }

    public String GetSerialPortName() {
        String portName;
        if (UseCustomPortName.isSelected()) {
            portName = CustomPortName.getText().trim();
        } else {
            portName = Port.getSelectedItem().toString();
        }
        return portName;
    }

    public boolean SetSerialPortParams() {
        boolean success = false;
        String portName = GetSerialPortName();
        try {
            success = serialPort.setParams(nSpeed,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE,
                    PortRTS.isSelected(),
                    PortDTR.isSelected());
        } catch (SerialPortException e) {
            log(e.toString());
        }
        if (!success) {
            log("错误设置端口" + portName + " 参数.");
        }
        UpdateLED();
        return success;
    }

    public boolean portOpen() {
        String portName = GetSerialPortName();
        nSpeed = Integer.parseInt((String) Speed.getSelectedItem());
        if (pOpen) {
            try {
                serialPort.closePort();
            } catch (SerialPortException e) {
            }
        } else {
            log("尝试打开串口" + portName + ", 波特率 " + Integer.toString(nSpeed) + ", 8N1");
        }
        serialPort = new SerialPort(portName);
        pOpen = false;
        boolean success;
        try {
            success = serialPort.openPort();
            if (!success) {
                log("打开串口错误" + portName);
                return success;
            }
            SetSerialPortParams();
            serialPort.addEventListener(new PortReader(), portMask);
        } catch (SerialPortException ex) {
            log(ex.toString());
            success = false;
        }
        pOpen = success;
        if (pOpen) {
            log("打开端口" + portName + " - 成功.");
            TerminalAdd("\r\n打开端口 " + Speed.getSelectedItem() + "\r\n");
            CheckComm();
        }
        return pOpen;

    }

    public void CheckComm() {
        if (!AutodetectFirmware.isSelected()) {
            portJustOpen = false;
            return;
        }
        portJustOpen = true;
        TerminalAdd("\r\n与单片机通信...");
        checker = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (portJustOpen) {
                    btnSend("");  // only CR+LF
                    TerminalAdd(".");
                    if (Terminal.getCaretOffsetFromLineStart() >= 10) {
                        TerminalAdd("\r\n");
                    }
                } else {
                    try {
                        openTimeout.stop();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                }
            }
        };
        openTimeout = new Timer(3000, checker);
        openTimeout.setRepeats(false);
        openTimeout.setInitialDelay(3000);
        openTimeout.start();
    }

    public void portClose() {
        boolean success = false;
        if (portJustOpen) {
            try {
                openTimeout.stop();
            } catch (Exception e) {
                log(e.toString());
            }
        }
        try {
            success = serialPort.closePort();
        } catch (SerialPortException ex) {
            log(ex.toString());
        }
        if (success) {
            TerminalAdd("\r\n端口关闭\r\n");
            log("端口关闭 " + Port.getSelectedItem().toString() + " - 成功.");
        } else {
            log("端口关闭 " + Port.getSelectedItem().toString() + " - 未知错误.");

        }
        pOpen = false;
        if (Open.isSelected()) {
            Open.setSelected(false);
        }
        UpdateLED();
        ClearNodeFileManager();
    }
    
    public void SendCommand() {
        if (SendCommand.isEnabled() == false || pOpen == false || portJustOpen) {
            log("端口未打开，操作失败。");
            return;
        }
        String cmd;
        try {
            cmd = Command.getSelectedItem().toString();
        } catch (Exception e) {
            cmd = "";
        }

        //Autoclean History --ADDED by Mike, DL2ZAP --
        //if (Autoclean.isSelected()) {   // ToDo: create Checkbox "Autoclean & uncomment this line
        if (true) { // ToDo: After creating Checkbox delete this line
            int eintraege = Command.getItemCount();
            //System.out.println("Start cleaning");
            for (int lv1 = 0; lv1 < eintraege; lv1++) {
                //System.out.print("Eintrag:" + lv1 +" : "+Command.getItemAt(lv1));
                if (Command.getItemAt(lv1).equals(cmd)) {
                    // System.out.println(" Doppelt, entfernt!");
                    Command.removeItemAt(lv1);
                    lv1--;  // re-read this Entry because List has moved up the Follower
                } else {
                    // System.out.println(" OK.");
                }
            }
        }

        // System.out.println("Adding Command:" + cmd );
        int eintraege = Command.getItemCount();

        Command.setSelectedIndex(Command.getItemCount() - 1); // Place Index on last Entry
        Command.addItem(cmd); // Add to History after last Position
        Command.setSelectedIndex(Command.getItemCount() - 1); // Place Index on new last Entry
        // End of Autoclean-Procedure

        //Command.addItem(cmd); // Add to History
        if (CR.isSelected()) {
            cmd += (char) 13;
        }
        if (LF.isSelected()) {
            cmd += (char) 10;
        }
        send(cmd, true);
        // History trim
        if (Command.getItemCount() > 20) {
            Command.removeItemAt(0);
        }
        //Command.setSelectedIndex(Command.getItemCount()-1);
    }

    public String addCRLF(String s) {
        String r = s;
        r += (char) 13;
        if (OptionNodeMCU.isSelected()) {
            r += (char) 10;
        }
        return r;
    }

    public String addCR(String s) {
        String r = s;
        r += (char) 13;
        return r;
    }

    public void btnSend(String s) {
        send(addCRLF(s), true);
    }

    public void btnSendEcho(String s) {
        if (Terminal.getCaretOffsetFromLineStart() > 0) {
            TerminalAdd("\r\n");
        }
        TerminalAdd(s);
        TerminalAdd("\r\n");
        btnSend(s);
    }

    private void finalInit() {
        final Image im = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/ESP8266-64x64.png"));
        setIconImage(im);

        setLocationRelativeTo(null); // window centered

        for(JRadioButtonMenuItem menuItem: ESPlorer.LAFselection.values())
        {
            menuItem.addActionListener((java.awt.event.ActionEvent evt) -> {
                MenuItemViewLookAndFeelActionPerformed(evt);
            });
            buttonGroupLF.add(menuItem);
            MenuView.add(menuItem);
            menuItem.setVisible(true);
            log("LAF" + menuItem.getActionCommand());

            //默认系统主题
            if(menuItem.getText().indexOf("系统")!=-1){
                menuItem.doClick();
            }
        }

        LED_GREY = new javax.swing.ImageIcon(getClass().getResource("/resources/led_grey.png"));
        LED_GREEN = new javax.swing.ImageIcon(getClass().getResource("/resources/led_green.png"));
        LED_RED = new javax.swing.ImageIcon(getClass().getResource("/resources/led_red.png"));
        LED_BLUE = new javax.swing.ImageIcon(getClass().getResource("/resources/led_blue.png"));

        SnippetScrollPane.setLineNumbersEnabled(true);
        SnippetText.setFadeCurrentLineHighlight(true);
        SnippetText.setPaintMarkOccurrencesBorder(true);
        SnippetText.setPaintMatchedBracketPair(true);
        SnippetText.setAntiAliasingEnabled(true);
        SnippetText.setTabsEmulated(true);
        snippetButtons.add(ButtonSnippet0);
        snippetButtons.add(ButtonSnippet1);
        snippetButtons.add(ButtonSnippet2);
        snippetButtons.add(ButtonSnippet3);
        snippetButtons.add(ButtonSnippet4);
        snippetButtons.add(ButtonSnippet5);
        snippetButtons.add(ButtonSnippet6);
        snippetButtons.add(ButtonSnippet7);
        snippetButtons.add(ButtonSnippet8);
        snippetButtons.add(ButtonSnippet9);
        snippetButtons.add(ButtonSnippet10);
        snippetButtons.add(ButtonSnippet11);
        snippetButtons.add(ButtonSnippet12);
        snippetButtons.add(ButtonSnippet13);
        snippetButtons.add(ButtonSnippet14);
        snippetButtons.add(ButtonSnippet15);

        FileLayeredPane1 = new ArrayList<>();
        TextScroll1 = new ArrayList<>();
        TextEditor1 = new ArrayList<>();
        FileLayeredPaneLayout1 = new ArrayList<>();
        provider = new ArrayList<>();
        ac = new ArrayList<>();
        iFile = new ArrayList<>();
        FileChanged = new ArrayList<>();

        FileAsButton = new ArrayList<>();
        PyFileAsButton = new ArrayList<>();

        FilePopupMenu = new ArrayList<>();
        FilePopupMenuItem = new ArrayList<>();

        FilesTabbedPane.removeAll();

        LoadPrefs();
        LoadSnippets();

        if (OptionNodeMCU.isSelected()) {
            Terminal.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LUA);
        } else {
            Terminal.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
        }

        AddTab(""); // iTab = 0

        try {
            donate_uri = new URI("https://www.paypal.com/donate/?token=O-oZBUWcB5UBzh1TRfQEzeo505G-p8zfyDeaMpHrciv6kUND-m3_Zh0YuBQoM7_LxDMg_W&country.x=US&locale.x=US");
            homepage_uri = new URI("http://esp8266.ru/esplorer/");
            micropython_doc = new URI("http://docs.micropython.org/en/latest/esp8266/");
            api_en_uri = new URI("http://nodemcu.readthedocs.org/");
            iot_manager = new URI("https://play.google.com/store/apps/details?id=ru.esp8266.iotmanager");
            changelog_uri = new URI("https://github.com/nodemcu/nodemcu-firmware/wiki");
            nodemcu_download_latest_uri = new URI("https://github.com/nodemcu/nodemcu-firmware/blob/master/pre_build/latest/nodemcu_latest.bin?raw=true");
            nodemcu_download_dev_uri = new URI("https://github.com/nodemcu/nodemcu-firmware/releases");
            flasher_uri = new URI("https://github.com/nodemcu/nodemcu-flasher");
            // adv links start
            // Please, do not modify
            buy_nodeMCU = new URI("http://goo.gl/GRiJpq");
            buy_esp8266 = new URI("http://goo.gl/4kdUSO");
            buy_esd12 = new URI("http://goo.gl/GexlwM");
            buy_other = new URI("http://goo.gl/J2GCSx");
            // adv links end
            esp8266com_uri = new URI("http://www.esp8266.com/viewtopic.php?f=22&t=882");
            esp8266ru_uri = new URI("http://esp8266.ru/forum/threads/esplorer.34/");
            esplorer_latest = new URI("http://esp8266.ru/esplorer/#download");
            esplorer_source = new URI("https://github.com/4refr0nt/ESPlorer");

        } catch (Exception e) {
            log(e.toString());
        }
        FileAsButton1.setVisible(false);
        FileRenamePanel.setVisible(false);
        PyFileAsButton1.setVisible(false);
    }

    private void LoadPrefs() {
        // Settings - Firmware
        workDir = prefs.get(PATH, "");
        chooser = new JFileChooser(workDir);
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooser.setMultiSelectionEnabled(false);
        chooser.setCurrentDirectory(new File(workDir));

        String SavedFirmware = prefs.get(FIRMWARE, "NodeMCU");
        log("加载已保存设置: 固件:" + SavedFirmware);
        if (SavedFirmware.equals("NodeMCU")) {
            SetFirmwareType(FIRMWARE_NODEMCU);
        } else if (SavedFirmware.equals("MicroPython")) {
            SetFirmwareType(FIRMWARE_MPYTHON);
        } else {
            SetFirmwareType(FIRMWARE_AT);
        }
        FileAutoSaveDisk.setSelected(prefs.getBoolean(FILE_AUTO_SAVE_DISK, true));
        FileAutoSaveESP.setSelected(prefs.getBoolean(FILE_AUTO_SAVE_ESP, true));
        FileAutoRun.setSelected(prefs.getBoolean(FILE_AUTO_RUN, true));
        EditorTheme.setSelectedIndex(prefs.getInt(COLOR_THEME, 1));
        Delay.setValue(prefs.getInt(DELAY, 0));
        AnswerDelay.setValue(prefs.getInt(TIMEOUT, 3));
        DumbMode.setSelected(prefs.getBoolean(DUMB_MODE, false));
        TurboMode.setSelected(prefs.getBoolean(TURBO_MODE, false));
        LineDelay.setValue(prefs.getInt(LINE_DELAY, 200));
        // Font size
        Terminal.setFont(Terminal.getFont().deriveFont(prefs.getFloat(TERMINAL_FONT_SIZE, TERMINAL_FONT_SIZE_DEFAULT)));
        SnippetText.setFont(SnippetText.getFont().deriveFont(prefs.getFloat(EDITOR_FONT_SIZE, EDITOR_FONT_SIZE_DEFAULT)));
        Log.setFont(Log.getFont().deriveFont(prefs.getFloat(LOG_FONT_SIZE, LOG_FONT_SIZE_DEFAULT)));
        LogMax = prefs.getInt(LOG_MAX_SIZE, LogMax);
        LogMaxSize.setText(Integer.toString(LogMax / 1024));
        TerminalMax = prefs.getInt(TERMINAL_MAX_SIZE, TerminalMax);
        TerminalMaxSize.setText(Integer.toString(TerminalMax / 1024));
        AutoScroll.setSelected(prefs.getBoolean(AUTO_SCROLL, true));
        MenuItemViewLog.setSelected(prefs.getBoolean(SHOW_LOG, false));
        MenuItemViewToolbar.setSelected(prefs.getBoolean(SHOW_TOOLBAR, true));
        MenuItemViewLeftExtra.setSelected(prefs.getBoolean(SHOW_EXTRA_LEFT, true));
        MenuItemViewRightExtra.setSelected(prefs.getBoolean(SHOW_EXTRA_RIGHT, true));
        MenuItemViewSnippets.setSelected(prefs.getBoolean(SHOW_SNIP_RIGHT, true));
        MenuItemViewFileManager.setSelected(prefs.getBoolean(SHOW_FM_RIGHT, true));
        MenuItemViewDonate.setSelected(prefs.getBoolean(SHOW_DONATE, false));
        DonateSmall.setVisible(!MenuItemViewDonate.isSelected());
        UseCustomPortName.setSelected(prefs.getBoolean(USE_CUSTOM_PORT, false));
        CustomPortName.setText(prefs.get(CUSTOM_PORT_NAME, "/dev/AnySerialDevice"));
        PortDTR.setSelected(prefs.getBoolean(PORT_DTR, false));
        PortRTS.setSelected(prefs.getBoolean(PORT_RTS, false));
        UseExternalEditor.setSelected(prefs.getBoolean(USE_EXT_EDITOR, false));
        EOL.setSelected(prefs.getBoolean(SHOW_EOL, false));
        Condensed.setSelected(prefs.getBoolean(CONDENSED, false));
        AutodetectFirmware.setSelected(prefs.getBoolean(AUTODETECT, true));
        CommandEcho.setSelected(prefs.getBoolean(COMMAND_ECHO, true));
        log("加载已保存设置: 完成。");
    }

    private void AddNodeFileButton(String FileName, int size) {
        FileAsButton.add(new javax.swing.JButton());
        int i = FileAsButton.size() - 1;
        FileAsButton.get(i).setText(FileName);
        FileAsButton.get(i).setAlignmentX(0.5F);
        FileAsButton.get(i).setMargin(new java.awt.Insets(2, 2, 2, 2));
        FileAsButton.get(i).setMaximumSize(new java.awt.Dimension(130, 25));
        FileAsButton.get(i).setPreferredSize(new java.awt.Dimension(130, 25));
        FileAsButton.get(i).setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        //FileAsButton.get(i).setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
        FileAsButton.get(i).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileAsButton1ActionPerformed(evt);
            }
        });
        // PopUp menu
        FilePopupMenu.add(new javax.swing.JPopupMenu());
        int x = FilePopupMenu.size() - 1;
        int y;
        // PopUp menu items
        if (FileName.endsWith(".lua")) {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/lua.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", 左键单击—运行，右键单击—其他操作");
            AddMenuItemRun(x, FileName);
            AddMenuItemCompile(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemView(x, FileName);
            AddMenuItemDump(x, FileName);
            AddMenuItemEdit(x, FileName, size);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        } else if (FileName.endsWith(".lc")) {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/lc.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", 左键单击—运行，右键单击—其他操作");
            AddMenuItemRun(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemDump(x, FileName);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        } else {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", 左键单击—运行，右键单击—其他操作");
            AddMenuItemView(x, FileName);
            AddMenuItemDump(x, FileName);
            AddMenuItemEdit(x, FileName, size);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        }

        FileAsButton.get(i).setComponentPopupMenu(FilePopupMenu.get(x));
        NodeFileManagerPane.add(FileAsButton.get(i));
    }

    private void AddMenuItemSeparator(int x) {
        FilePopupMenu.get(x).add(new javax.swing.JPopupMenu.Separator());
    }

    private void AddMenuItemEdit(int x, String FileName, int size) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/edit.png")));
        FilePopupMenuItem.get(y).setText("编辑" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("从ESP下载文件并在新的编辑器窗口中打开");
        FilePopupMenuItem.get(y).setActionCommand(FileName + "Size:" + Integer.toString(size));
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DownloadCommand = "EDIT";
                FileDownload(evt.getActionCommand());
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemDownload(int x, String FileName, int size) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/download.png")));
        FilePopupMenuItem.get(y).setText("下载" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("从ESP下载文件并保存到磁盘");
        FilePopupMenuItem.get(y).setActionCommand(FileName + "Size:" + Integer.toString(size));
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DownloadCommand = "DOWNLOAD";
                FileDownload(evt.getActionCommand());
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemRun(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/play.png")));
        FilePopupMenuItem.get(y).setText("运行" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("执行命令 dofile(\"" + FileName + "\") 来运行这个文件");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSend("dofile(\"" + evt.getActionCommand() + "\")");
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemCompile(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/wizard.png")));
        FilePopupMenuItem.get(y).setText("编译" + FileName + "成 .lc");
        FilePopupMenuItem.get(y).setToolTipText("执行命令 node.compile(\"" + FileName + "\")");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSend("node.compile(\"" + evt.getActionCommand() + "\")");
                try {
                    Thread.sleep(500L);
                } catch (Exception e) {
                }
                FileListReload.doClick();
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemRename(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/rename.png")));
        FilePopupMenuItem.get(y).setText("重命名" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("执行命令 file.rename(\"" + FileName + "\",\"NewName\")");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileRename.setText(evt.getActionCommand());
                FileRenameLabel.setText(evt.getActionCommand());
                FileRenamePanel.setEnabled(true);
                FileRenamePanel.setVisible(true);
                FileRename.grabFocus();
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemRemove(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/trash.png")));
        FilePopupMenuItem.get(y).setText("移除" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("执行命令file.remove(\"" + FileName + "\") 并从NodeMCU文件系统中删除文件");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FileRemoveESP(evt.getActionCommand());
                // FileListReload not needed
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemView(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/view.png")));
        FilePopupMenuItem.get(y).setText("视图" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("在终端里查看" + FileName + "的内容");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ViewFile(evt.getActionCommand());
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddMenuItemDump(int x, String FileName) {
        int y;
        FilePopupMenuItem.add(new javax.swing.JMenuItem());
        y = FilePopupMenuItem.size() - 1;
        FilePopupMenuItem.get(y).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/dump.png")));
        FilePopupMenuItem.get(y).setText("十六进制转储" + FileName);
        FilePopupMenuItem.get(y).setToolTipText("在终端里" + FileName + "查看十六进制转储");
        FilePopupMenuItem.get(y).setActionCommand(FileName);
        FilePopupMenuItem.get(y).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                HexDump(evt.getActionCommand());
            }
        });
        FilePopupMenu.get(x).add(FilePopupMenuItem.get(y));
    }

    private void AddTab(String s) {
        int i = FilesTabbedPane.getTabCount();

        FileLayeredPane1.add(new javax.swing.JLayeredPane());
        TextScroll1.add(new org.fife.ui.rtextarea.RTextScrollPane());
        TextEditor1.add(new org.fife.ui.rsyntaxtextarea.RSyntaxTextArea());
        iFile.add(new File(""));
        FileChanged.add(false);
        provider.add(createCompletionProvider());
        ac.add(new AutoCompletion(provider.get(i)));
        ac.get(i).install(TextEditor1.get(i));

        FileLayeredPaneLayout1.add(new javax.swing.GroupLayout(FileLayeredPane1.get(i)));

        if (OptionNodeMCU.isSelected()) {
            TextEditor1.get(i).setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LUA);
        } else {
            TextEditor1.get(i).setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
        }
        TextEditor1.get(i).setColumns(20);
        TextEditor1.get(i).setRows(5);
        TextEditor1.get(i).setDragEnabled(false);
        TextEditor1.get(i).setFadeCurrentLineHighlight(true);
        TextEditor1.get(i).setPaintMarkOccurrencesBorder(true);
        TextEditor1.get(i).setPaintMatchedBracketPair(true);
        TextEditor1.get(i).setPopupMenu(ContextMenuEditor);
        TextEditor1.get(i).setCodeFoldingEnabled(false);
        TextEditor1.get(i).setAntiAliasingEnabled(true);
        TextEditor1.get(i).setTabsEmulated(true);
        TextEditor1.get(i).setBracketMatchingEnabled(true);
        TextEditor1.get(i).setTabSize(4);
        TextEditor1.get(i).addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                TextEditorCaretUpdate(evt);
            }
        });
        TextEditor1.get(i).addActiveLineRangeListener(new org.fife.ui.rsyntaxtextarea.ActiveLineRangeListener() {
            public void activeLineRangeChanged(org.fife.ui.rsyntaxtextarea.ActiveLineRangeEvent evt) {
                TextEditorActiveLineRangeChanged(evt);
            }
        });
        TextEditor1.get(i).addInputMethodListener(new java.awt.event.InputMethodListener() {
            public void caretPositionChanged(java.awt.event.InputMethodEvent evt) {
                TextEditorCaretPositionChanged(evt);
            }

            public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) {
                TextEditorInputMethodTextChanged(evt);
            }
        });
        TextEditor1.get(i).addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                TextEditorKeyTyped(evt);
            }
        });
        TextEditor1.get(i).addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                int i;
                for (i = 0; i < TextEditor1.size(); i++) {
                    TextEditor1.get(i).setEditable(!UseExternalEditor.isSelected());
                }
            }
        });
        TextScroll1.get(i).setViewportView(TextEditor1.get(i));
        TextScroll1.get(i).setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        TextScroll1.get(i).setIconRowHeaderEnabled(false);
        TextScroll1.get(i).setLineNumbersEnabled(true);
        TextScroll1.get(i).setFoldIndicatorEnabled(true);

        FileLayeredPane1.get(i).setLayout(FileLayeredPaneLayout1.get(i));
        FileLayeredPaneLayout1.get(i).setHorizontalGroup(
                FileLayeredPaneLayout1.get(i).createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(TextScroll1.get(i), javax.swing.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE)
        );
        FileLayeredPaneLayout1.get(i).setVerticalGroup(
                FileLayeredPaneLayout1.get(i).createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(TextScroll1.get(i), javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
        );
        FileLayeredPane1.get(i).setLayer(TextScroll1.get(i), javax.swing.JLayeredPane.DEFAULT_LAYER);

        FilesTabbedPane.addTab(NewFile, FileLayeredPane1.get(i));

        FilesTabbedPane.setSelectedIndex(i);
        iTab = i;
        SetTheme(EditorTheme.getSelectedIndex(), false);
        FileLabelUpdate();
        if (UseExternalEditor.isSelected()) {
            TextEditor1.get(i).setEditable(false);
        }
        TextEditor1.get(i).setText(s);
    }

    private void SetTheme(int t, boolean all) {
        String res;
        if (t == 1) {
            res = "/org/fife/ui/rsyntaxtextarea/themes/dark.xml";
        } else if (t == 2) {
            res = "/org/fife/ui/rsyntaxtextarea/themes/eclipse.xml";
        } else if (t == 3) {
            res = "/org/fife/ui/rsyntaxtextarea/themes/idea.xml";
        } else if (t == 4) {
            res = "/org/fife/ui/rsyntaxtextarea/themes/vs.xml";
        } else if (t == 5) {
            res = "/org/fife/ui/rsyntaxtextarea/themes/default-alt.xml";
        } else {
            res = "/org/fife/ui/rsyntaxtextarea/themes/default.xml";
        }
        try {
            Theme theme = Theme.load(getClass().getResourceAsStream(res));
            if (all) {
                for (int i = 0; i < FilesTabbedPane.getTabCount(); i++) {
                    theme.apply(TextEditor1.get(i));
                    TextEditor1.get(i).setFont(TextEditor1.get(i).getFont().deriveFont(prefs.getFloat(EDITOR_FONT_SIZE, EDITOR_FONT_SIZE_DEFAULT)));
                }
                theme.apply(SnippetText);
                SnippetText.setFont(SnippetText.getFont().deriveFont(prefs.getFloat(EDITOR_FONT_SIZE, EDITOR_FONT_SIZE_DEFAULT)));
                theme.apply(Terminal);
                Terminal.setFont(Terminal.getFont().deriveFont(prefs.getFloat(TERMINAL_FONT_SIZE, TERMINAL_FONT_SIZE_DEFAULT)));
                themeTextBackground = SnippetText.getBackground();
                //SnippetText.setBackground(SnippetTopPane.getBackground());
                log("设置新的色彩主题:成功。");
            } else {
                theme.apply(TextEditor1.get(iTab));
                TextEditor1.get(iTab).setFont(TextEditor1.get(iTab).getFont().deriveFont(prefs.getFloat(EDITOR_FONT_SIZE, EDITOR_FONT_SIZE_DEFAULT)));
            }
        } catch (IOException e) {
            log(e.toString());
            log("设置新的颜色主题:失败。");
        }
    }

    private void RemoveTab() {
        if (FilesTabbedPane.getTabCount() <= 1) {
            iTab = 0;
            TextEditor1.get(iTab).setText("");
            TextEditor1.get(iTab).discardAllEdits();
            FilesTabbedPane.setTitleAt(iTab, NewFile);
            iFile.set(iTab, new File(""));
            FileLabelUpdate();
            FileChanged.set(iTab, false);
            UpdateEditorButtons();
            log("FileTab清除:成功。");
        } else {
            iFile.remove(iTab);
            FileChanged.remove(iTab);
            ac.remove(iTab);
            provider.remove(iTab);
            TextEditor1.remove(iTab);
            TextScroll1.remove(iTab);
            FileLayeredPaneLayout1.remove(iTab);
            FileLayeredPane1.remove(iTab);
            FilesTabbedPane.removeTabAt(iTab);
            FilesTabbedPane.setSelectedIndex(iTab);
            FileLabelUpdate();
            log("FileTab:删除成功。");
        }
    }

    private boolean isChanged() {
        if (UseExternalEditor.isSelected()) {
            return false;
        }
        try {
            if (FileChanged.get(iTab)) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        if (TextEditor1.get(iTab).canUndo()) {
            return true;
        }
        if (TextEditor1.get(iTab).canRedo()) {
            return true;
        }
        return false;
    }

    private int Dialog(String msg, int btn) {
        this.setAlwaysOnTop(false);
        Toolkit.getDefaultToolkit().beep();
        int returnVal = JOptionPane.showConfirmDialog(null, msg, "注意", btn, JOptionPane.WARNING_MESSAGE);
        this.setAlwaysOnTop(AlwaysOnTop.isSelected());
        return returnVal;
    }

    private CompletionProvider createCompletionProvider() {

        DefaultCompletionProvider provider = new DefaultCompletionProvider();
        if (OptionNodeMCU.isSelected()) {

            provider.addCompletion(new BasicCompletion(provider, "function end"));
            provider.addCompletion(new BasicCompletion(provider, "function"));
            provider.addCompletion(new BasicCompletion(provider, "function return end"));
            provider.addCompletion(new BasicCompletion(provider, "end"));
            provider.addCompletion(new BasicCompletion(provider, "do"));
            provider.addCompletion(new BasicCompletion(provider, "print(\"\")"));
            provider.addCompletion(new BasicCompletion(provider, "if"));
            provider.addCompletion(new BasicCompletion(provider, "else"));
            provider.addCompletion(new BasicCompletion(provider, "elseif"));
            provider.addCompletion(new BasicCompletion(provider, "if else end"));
            provider.addCompletion(new BasicCompletion(provider, "while"));
            provider.addCompletion(new BasicCompletion(provider, "while do end"));
            provider.addCompletion(new BasicCompletion(provider, "do end"));
            provider.addCompletion(new BasicCompletion(provider, "for"));
            provider.addCompletion(new BasicCompletion(provider, "for do end"));
            provider.addCompletion(new BasicCompletion(provider, "repeat"));
            provider.addCompletion(new BasicCompletion(provider, "until"));
            provider.addCompletion(new BasicCompletion(provider, "repeat until"));
            provider.addCompletion(new BasicCompletion(provider, "for"));
            provider.addCompletion(new BasicCompletion(provider, "for key, value in pairs() do\r\nend"));
            provider.addCompletion(new BasicCompletion(provider, "for do end"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.setmode(wifi.STATION)"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.getmode()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.startsmart()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.stopsmart()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.config(\"SSID\",\"password\")"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.connect()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.disconnect()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.autoconnect()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.getip()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.getmac()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.getap()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.sta.status()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.ap.config()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.ap.getip()"));
            provider.addCompletion(new BasicCompletion(provider, "wifi.ap.getmac()"));
            provider.addCompletion(new BasicCompletion(provider, "gpio.mode(pin,gpio.OUTPUT)"));
            provider.addCompletion(new BasicCompletion(provider, "gpio.write(pin,gpio.HIGH)"));
            provider.addCompletion(new BasicCompletion(provider, "gpio.write(pin,gpio.LOW)"));
            provider.addCompletion(new BasicCompletion(provider, "gpio.read(pin)"));
            provider.addCompletion(new BasicCompletion(provider, "gpio.trig(0, \"act\",func)"));
            provider.addCompletion(new BasicCompletion(provider, "conn=net.createConnection(net.TCP, 0)"));
            provider.addCompletion(new BasicCompletion(provider, "net.createConnection(net.TCP, 0)"));
            provider.addCompletion(new BasicCompletion(provider, "on(\"receive\", function(conn, payload) print(payload) end )"));
            provider.addCompletion(new BasicCompletion(provider, "connect(80,\"0.0.0.0\")"));
            provider.addCompletion(new BasicCompletion(provider, "send(\"GET / HTTP/1.1\\r\\nHost: www.baidu.com\\r\\nConnection: keep-alive\\r\\nAccept: */*\\r\\n\\r\\n\")"));
            provider.addCompletion(new BasicCompletion(provider, "srv=net.createServer(net.TCP)"));
            provider.addCompletion(new BasicCompletion(provider, "srv:listen(80,function(conn) \nconn:on(\"receive\",function(conn,payload) \nprint(payload) \nconn:send(\"<h1> Hello, NodeMcu.</h1>\")\nend) \nconn:on(\"sent\",function(conn) conn:close() end)\nend)"));
            provider.addCompletion(new BasicCompletion(provider, "net.createServer(net.TCP, timeout)"));
            provider.addCompletion(new BasicCompletion(provider, "net.server.listen(port,[ip],function(net.socket))"));
            provider.addCompletion(new BasicCompletion(provider, "dns(domain, function(net.socket, ip))"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.setduty(0,0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.getduty(0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.setup(0,0,0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.start(0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.close(0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.setclock(0, 100)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.getclock(0)"));
            provider.addCompletion(new BasicCompletion(provider, "pwm.close(0)"));
            provider.addCompletion(new BasicCompletion(provider, "file.open(\"\",\"r\")"));
            provider.addCompletion(new BasicCompletion(provider, "file.writeline()"));
            provider.addCompletion(new BasicCompletion(provider, "file.readline()"));
            provider.addCompletion(new BasicCompletion(provider, "file.write()"));
            provider.addCompletion(new BasicCompletion(provider, "file.close()"));
            provider.addCompletion(new BasicCompletion(provider, "file.remove()"));
            provider.addCompletion(new BasicCompletion(provider, "file.flush()"));
            provider.addCompletion(new BasicCompletion(provider, "file.seek()"));
            provider.addCompletion(new BasicCompletion(provider, "file.list()"));
            provider.addCompletion(new BasicCompletion(provider, "node.restart()"));
            provider.addCompletion(new BasicCompletion(provider, "node.dsleep()"));
            provider.addCompletion(new BasicCompletion(provider, "node.chipid()"));
            provider.addCompletion(new BasicCompletion(provider, "node.heap()"));
            provider.addCompletion(new BasicCompletion(provider, "node.key(type, function())"));
            provider.addCompletion(new BasicCompletion(provider, "node.led()"));
            provider.addCompletion(new BasicCompletion(provider, "node.input()"));
            provider.addCompletion(new BasicCompletion(provider, "node.output()"));
            provider.addCompletion(new BasicCompletion(provider, "tmr.alarm(0,1000,1,function()\nend)"));
            provider.addCompletion(new BasicCompletion(provider, "tmr.delay()"));
            provider.addCompletion(new BasicCompletion(provider, "tmr.now()"));
            provider.addCompletion(new BasicCompletion(provider, "tmr.stop(id)"));
            provider.addCompletion(new BasicCompletion(provider, "tmr.wdclr()"));
            provider.addCompletion(new BasicCompletion(provider, "dofile(\"\")"));
        } else { // MicroPython
            provider.addCompletion(new BasicCompletion(provider, "import "));
            provider.addCompletion(new BasicCompletion(provider, "import network"));
            provider.addCompletion(new BasicCompletion(provider, "import time"));
            provider.addCompletion(new BasicCompletion(provider, "import Timer"));
            provider.addCompletion(new BasicCompletion(provider, "from machine import Pin"));
            provider.addCompletion(new BasicCompletion(provider, "from machine import Pin, PWM"));
            provider.addCompletion(new BasicCompletion(provider, "from machine import ADC"));
            provider.addCompletion(new BasicCompletion(provider, "from machine import Pin, SPI"));
            provider.addCompletion(new BasicCompletion(provider, "from machine import Pin, I2C"));
            provider.addCompletion(new BasicCompletion(provider, "import onewire"));
            provider.addCompletion(new BasicCompletion(provider, "from neopixel import NeoPixel"));
            provider.addCompletion(new BasicCompletion(provider, "import neopixel"));
            provider.addCompletion(new BasicCompletion(provider, "import esp"));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, "json"));
            provider.addCompletion(new BasicCompletion(provider, "ubinascii.hexlify(data[, sep])"));
            provider.addCompletion(new BasicCompletion(provider, "ubinascii.unhexlify(data)"));
            provider.addCompletion(new BasicCompletion(provider, "ubinascii.a2b_base64(data)"));
            provider.addCompletion(new BasicCompletion(provider, "ubinascii.b2a_base64(data)"));
            provider.addCompletion(new BasicCompletion(provider, "machine.freq(160000000)"));
            provider.addCompletion(new BasicCompletion(provider, "esp.osdebug(None)"));
            provider.addCompletion(new BasicCompletion(provider, "esp.osdebug(0)"));
            provider.addCompletion(new BasicCompletion(provider, "wlan = network.WLAN(network.STA_IF)"));
            provider.addCompletion(new BasicCompletion(provider, "wlan.active(True)"));
            provider.addCompletion(new BasicCompletion(provider, "wlan.scan()"));
            provider.addCompletion(new BasicCompletion(provider, "wlan.isconnected()"));
            provider.addCompletion(new BasicCompletion(provider, "wlan.connect('essid', 'password')"));
            provider.addCompletion(new BasicCompletion(provider, "wlan.ifconfig()"));
            provider.addCompletion(new BasicCompletion(provider, "ap = network.WLAN(network.AP_IF)"));
            provider.addCompletion(new BasicCompletion(provider, "ap.active(True)"));
            provider.addCompletion(new BasicCompletion(provider, "ap.config(essid='ESP-AP')"));
            provider.addCompletion(new BasicCompletion(provider, "time.sleep(1)"));
            provider.addCompletion(new BasicCompletion(provider, "time.sleep_ms(500)"));
            provider.addCompletion(new BasicCompletion(provider, "time.sleep_us(10)"));
            provider.addCompletion(new BasicCompletion(provider, "time.ticks_diff(start, time.ticks_ms())"));
            provider.addCompletion(new BasicCompletion(provider, "tim = Timer(-1)"));
            provider.addCompletion(new BasicCompletion(provider, "tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))"));
            provider.addCompletion(new BasicCompletion(provider, "tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))"));
            provider.addCompletion(new BasicCompletion(provider, "Pin(0, Pin.OUT)"));
            provider.addCompletion(new BasicCompletion(provider, ".high()"));
            provider.addCompletion(new BasicCompletion(provider, ".low()"));
            provider.addCompletion(new BasicCompletion(provider, ".value(1)"));
            provider.addCompletion(new BasicCompletion(provider, "Pin(2, Pin.IN)"));
            provider.addCompletion(new BasicCompletion(provider, "Pin(4, Pin.IN, Pin.PULL_UP)"));
            provider.addCompletion(new BasicCompletion(provider, "Pin(5, Pin.OUT, value=1)"));
            provider.addCompletion(new BasicCompletion(provider, "PWM(Pin(0))"));
            provider.addCompletion(new BasicCompletion(provider, ".freq()"));
            provider.addCompletion(new BasicCompletion(provider, ".freq(1000)"));
            provider.addCompletion(new BasicCompletion(provider, ".duty()"));
            provider.addCompletion(new BasicCompletion(provider, ".duty(200)"));
            provider.addCompletion(new BasicCompletion(provider, ".deinit()"));
            provider.addCompletion(new BasicCompletion(provider, "PWM(Pin(2), freq=500, duty=512)"));
            provider.addCompletion(new BasicCompletion(provider, "ADC(0)"));
            provider.addCompletion(new BasicCompletion(provider, ".read()"));
            provider.addCompletion(new BasicCompletion(provider, "SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))"));
            provider.addCompletion(new BasicCompletion(provider, ".init(baudrate=200000)"));
            provider.addCompletion(new BasicCompletion(provider, ".readinto(buf)"));
            provider.addCompletion(new BasicCompletion(provider, ".write_readinto(b'1234', buf)"));
            provider.addCompletion(new BasicCompletion(provider, ".write_readinto(buf, buf)"));
            provider.addCompletion(new BasicCompletion(provider, "I2C(scl=Pin(5), sda=Pin(4), freq=100000)"));
            provider.addCompletion(new BasicCompletion(provider, "machine.RTC()"));
            provider.addCompletion(new BasicCompletion(provider, ".irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)"));
            provider.addCompletion(new BasicCompletion(provider, "machine.reset_cause()"));
            provider.addCompletion(new BasicCompletion(provider, "machine.DEEPSLEEP_RESET"));
            provider.addCompletion(new BasicCompletion(provider, "rtc.alarm(rtc.ALARM0, 10000)"));
            provider.addCompletion(new BasicCompletion(provider, ".scan()"));
            provider.addCompletion(new BasicCompletion(provider, ".reset()"));
            provider.addCompletion(new BasicCompletion(provider, "onewire.DS18B20(ow)"));
            provider.addCompletion(new BasicCompletion(provider, ".start_measure()"));
            provider.addCompletion(new BasicCompletion(provider, ".get_temp(rom)"));
            provider.addCompletion(new BasicCompletion(provider, "NeoPixel(pin, 8)"));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
            provider.addCompletion(new BasicCompletion(provider, ""));
        }
        /*
      provider.addCompletion(new ShorthandCompletion(provider, "sysout",
            "System.out.println(", "System.out.println("));
      provider.addCompletion(new ShorthandCompletion(provider, "syserr",
            "System.err.println(", "System.err.println("));
         */
        return provider;

    }

    private void FileLabelUpdate() {
        iTab = FilesTabbedPane.getSelectedIndex();
        if (isFileNew()) {
            FilePathLabel.setText("");
        } else {
            try {
                if (UseExternalEditor.isSelected()) {
                    FilePathLabel.setText("只读" + iFile.get(FilesTabbedPane.getSelectedIndex()).getPath());
                } else {
                    FilePathLabel.setText(iFile.get(FilesTabbedPane.getSelectedIndex()).getPath());
                }
            } catch (Exception e) {
                FilePathLabel.setText("");
            }
        }
        UpdateEditorButtons();
    }

    private int CloseFile() {
        if (UseExternalEditor.isSelected()) {
            return JOptionPane.YES_OPTION;
        }
        if (isChanged()) {
            log("文件发生了变化。问之前关闭。");
            int returnVal = Dialog("在关闭之前保存 \"" + FilesTabbedPane.getTitleAt(iTab) + "\" ？", JOptionPane.YES_NO_CANCEL_OPTION);
            if (returnVal == JOptionPane.YES_OPTION) {
                if (!SaveFile()) {
                    log("文件关闭:失败(文件未保存，关闭中止)");
                    return JOptionPane.CANCEL_OPTION;
                }
            } else if (returnVal == JOptionPane.CANCEL_OPTION) {
                log("用户选择:继续编辑。");
                return JOptionPane.CANCEL_OPTION;
            } else {
                log("用户选择:无论如何关闭。");
            }
        }
        RemoveTab();
        log("文件关闭:成功。");
        return JOptionPane.YES_OPTION;
    }

    private void ReloadFile() {
        if (isFileNew()) {
            return;
        }
        if (isChanged() && !UseExternalEditor.isSelected()) {
            log("文件重载:文件更改。问之前重新加载。");
            int returnVal = Dialog("放弃任何更改和重新加载文件从磁盘?", JOptionPane.YES_NO_OPTION);
            if (returnVal != JOptionPane.OK_OPTION) {
                log("文件重新加载失败(文件未保存，用户选择取消重新加载)");
                return;
            } else {
                log("文件重新加载:重新加载的用户选择。");
            }
        }
        if (LoadFile()) {
            log("文件重新加载:成功。");

        }
    }

    private class PortReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                try {
                    String data = serialPort.readString(event.getEventValue());
                    if (portJustOpen) {
                        TerminalAdd("有回应!与MCU建立沟通。\r\n自动侦测固件...\r\n");
                        portJustOpen = false;
                        try {
                            openTimeout.stop();
                        } catch (Exception e) {
                            log(e.toString());
                        }
                        UpdateButtons();
                        if (data.contains("\r\n>>>")) {
                            TerminalAdd("\r\n检测到MicroPython固件，请尝试获取版本...\r\n\r\n");
                            btnSend("import sys; print(\"MicroPython ver:\",sys.version_info)");
                            LeftTab.setSelectedIndex(0);
                            SetFirmwareType(FIRMWARE_MPYTHON);
                        } else if (data.contains("\r\n>")) {
                            TerminalAdd("\r\n检测到NodeMCU估计\r\n");
                            btnSend("=node.heap()");
                            LeftTab.setSelectedIndex(0);
                            SetFirmwareType(FIRMWARE_NODEMCU);
                        } else if (data.contains("\r\nERR")) {
                            TerminalAdd("\r\nAT-指令固件。\r\n");
                            btnSend("AT+GMR");
                            LeftTab.setSelectedIndex(1);
                            RightExtraButtons.setVisible(false);
                            RightSnippetsPane.setVisible(false);
                            NodeFileManagerPane.setVisible(false);
                            FirmwareType = FIRMWARE_AT;
                        } else {
                            TerminalAdd("\r\n无法自动检测固件，因为没有收到正确的答案(可能是未知的固件)。\r\n请重设模块或继续。\r\n");
                        }
                    } else if (LocalEcho) {
                        TerminalAdd(data);
                    } else if (data.contains("\r")) {
                        LocalEcho = true;
                        TerminalAdd(data.substring(data.indexOf("\r")));
                    }
                } catch (SerialPortException ex) {
                    log(ex.toString());
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("接收到未知的串口错误。");
            }
        }
    }

    private class PortExtraReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                String data = "";
                try {
                    data = serialPort.readString(event.getEventValue());
                } catch (SerialPortException ex) {
                    log(ex.toString());
                }
                data = data.replace(">> ", "");
                data = data.replace(">>", "");
                data = data.replace("\r\n> ", "");
                data = data.replace("\r\n\r\n", "\r\n");

                rcvBuf = rcvBuf + data;
                log("接收:" + data.replace("\r\n", "<CR><LF>"));
                TerminalAdd(data);
                if (rcvBuf.contains(sendBuf.get(j).trim())) {
                    // first, reset watchdog timer
                    try {
                        timeout.stop();
                    } catch (Exception e) {
                    }
                    /*
                    if (rcvBuf.contains("stdin:")) {
                        String msg[] = {"Interpreter error detected!", rcvBuf, "Click OK to continue."};
                        JOptionPane.showMessageDialog(null, msg);
                    }
                     */
                    rcvBuf = "";
                    if (j < sendBuf.size() - 1) {
                        if (timer.isRunning() || sendPending) {
                            // waiting
                        } else {
                            inc_j();
                            sendPending = true;
                            int div = sendBuf.size() - 1;
                            if (div == 0) {
                                div = 1;
                            }
                            ProgressBar.setValue((j * 100) / div);
                            timer.start();
                        }
                    } else {  // send done
                        StopSend();
                    }
                }
                if (rcvBuf.contains("powered by Lua 5.")) {
                    StopSend();
                    String msg[] = {"侦测到ESP模块重启!", "事件:内部NodeMCU异常或电源故障。", "请重试"};
                    JOptionPane.showMessageDialog(null, msg);
                }
                if (rcvBuf.contains("Type \"help()")) {
                    StopSend();
                    String msg[] = {"侦测到ESP模块重启!", "事件:内部MicroPython异常或电源故障。", "请重试"};
                    JOptionPane.showMessageDialog(null, msg);
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("接收到未知的串口错误。");
            }
        }
    }

    private class PortTurboReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                String data = "";
                try {
                    data = serialPort.readString(event.getEventValue());
                } catch (SerialPortException ex) {
                    log(ex.toString());
                }
                rcvBuf = rcvBuf + data;
                String l = data.replace("\r", "<CR>");
                l = l.replace("\n", "<LF>");
                l = l.replace("`", "<OK>");
                log("接收:" + l);
                TerminalAdd(data);
                if (rcvBuf.contains("> ")) {
                    try {
                        timeout.stop(); // first, reset watchdog timer
                    } catch (Exception e) {
                    }
                    rcvBuf = "";
                    if (j < sendBuf.size() - 1) {
                        if (timer.isRunning() || sendPending) {
                            // waiting
                        } else {
                            inc_j();
                            sendPending = true;
                            int div = sendBuf.size() - 1;
                            if (div == 0) {
                                div = 1;
                            }
                            ProgressBar.setValue((j * 100) / div);
                            timer.start();
                        }
                    } else { // send done
                        StopSend();
                    }
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("接收到未知的串口错误。");
            }
        }
    }
    
    private void StopSend() {
        try {
            serialPort.removeEventListener();
        } catch (Exception e) {
        }
        try {
            timer.stop();
        } catch (Exception e) {
        }
        try {
            timeout.stop();
        } catch (Exception e) {
        }
        try {
            serialPort.addEventListener(new PortReader(), portMask);
        } catch (SerialPortException e) {
        }
        SendUnLock();
        long duration = System.currentTimeMillis() - startTime;
        log("操作完成。持续时间 = " + Long.toString(duration) + " ms");
    }

    private boolean SendToESP(String str) {
        boolean success = false;
        if (!pOpen || portJustOpen) {
            log("串口未打开。取消了。");
            return success;
        }
        sendBuf = new ArrayList<String>();
        s = str.split("\r?\n");
        sendBuf.addAll(Arrays.asList(s));
        success = SendTimerStart();
        log("发送到ESP: 开始...");
        return success;
    }

    private boolean SendToESP(ArrayList<String> buf) {
        boolean success = false;
        if (!pOpen || portJustOpen) {
            log("发送到ESP: 端口没打开. 取消.");
            return success;
        }
        sendBuf = new ArrayList<String>();
        sendBuf.addAll(buf);
        if (OptionMicroPython.isSelected()) {
            sendBuf.add("");
            sendBuf.add("");
            sendBuf.add("");
        }
        success = SendTimerStart();
        log("发送到ESP: 开始...");
        return success;
    }

    private void WatchDog() {
        if (DumbMode.isSelected()) {
            return;
        }
        watchDog = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                StopSend();
                Toolkit.getDefaultToolkit().beep();
                TerminalAdd("ESP应答超时！命令中止！");
                log("等待ESP的答复-超时到了。命令中止。");
            }
        };
        int delay = AnswerDelay.getValue() * 1000;
        if (delay == 0) {
            delay = 300;
        }
        timeout = new Timer(delay, watchDog);
        timeout.setRepeats(false);
        timeout.setInitialDelay(delay);
        timeout.start();
    }

    private boolean nodeSaveFileESP(String ft) {
        boolean success = false;
        log("ESP保存文件: 尝试保存文件到ESP...");
        sendBuf = new ArrayList<String>();
        if (TurboMode.isSelected()) {
            return nodeSaveFileESPTurbo(ft);
        }
        sendBuf.add("file.remove(\"" + ft + "\");");
        sendBuf.add("file.open(\"" + ft + "\",\"w+\");");
        sendBuf.add("w = file.writeline;\r\n");
        s = TextEditor1.get(iTab).getText().split("\r?\n");
        for (String subs : s) {
            sendBuf.add("w([==[" + subs + "]==]);");
        }
        sendBuf.add("file.flush();file.close();");
        if (FileAutoRun.isSelected()) {
            sendBuf.add("dofile(\"" + ft + "\");");
        }
        // data ready
        success = SendTimerStart();
        log("ESP保存文件: 开始...");
        return success;
    }

    private boolean nodeSaveFileESPTurbo(String ft) {
        boolean success = false;
        log("ESP保存文件-兼容:在兼容模式下，尝试将文件保存到ESP...");
        sendBuf.add("local FILE=\"" + ft + "\" file.remove(FILE) file.open(FILE,\"w+\") uart.setup(0," + Integer.toString(nSpeed) + ",8,0,1,0)");
        sendBuf.add("ESP_Receiver=function(rcvBuf) if string.match(rcvBuf,\"^ESP_cmd_close\")==nil then file.write(string.gsub(rcvBuf, \'\\r\', \'\')) uart.write(0, \"> \") else uart.on(\"data\") ");
        sendBuf.add("file.flush() file.close() FILE=nil rcvBuf=nil ESP_Receiver=nil uart.setup(0," + Integer.toString(nSpeed) + ",8,0,1,1) str=\"\\r\\n--Done--\\r\\n> \" print(str) str=nil collectgarbage() end end uart.on(\"data\",'\\r',ESP_Receiver,0)");
        int pos1 = 0;
        int pos2 = 0;
        int size = 254;
        int l = TextEditor1.get(iTab).getText().length();
        String fragment;
        while (pos1 <= l) {
            pos2 = pos1 + size;
            if (pos2 > l) {
                pos2 = l;
            }
            fragment = new String(TextEditor1.get(iTab).getText().substring(pos1, pos2));
            sendBuf.add(fragment);
            pos1 += size;
        }
        sendBuf.add("ESP_cmd_close");
        sendBuf.add("\r\n");
        if (FileAutoRun.isSelected()) {
            sendBuf.add("dofile(\"" + ft + "\")");
        }
        success = SendTurboTimerStart();
        log("ESP保存文件-兼容: 开始...");
        return success;
    }

    public boolean SendTurboTimerStart() {
        startTime = System.currentTimeMillis();
        SendLock();
        rcvBuf = "";
        try {
            serialPort.removeEventListener();
        } catch (Exception e) {
        }
        try {
            serialPort.addEventListener(new PortTurboReader(), portMask);
        } catch (SerialPortException e) {
            log("兼容数据发送器:添加EventListener错误。取消了。");
            return false;
        }
        int delay = 0;
        j0();
        delay = Delay.getValue();
        if (delay == 0) {
            delay = 10;
        }
        taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (j < sendBuf.size()) {
                    send(addCR(sendBuf.get(j)), false);
                    sendPending = false;
                }
            }
        };
        timer = new Timer(delay, taskPerformer);
        timer.setRepeats(false);
        log("兼容数据发送器: 开始 \"智能模式\"");
        timer.setInitialDelay(delay);
        WatchDog();
        timer.start();
        return true;
    }

    private String addBS(String s) {
        String bs = "" + (char) java.awt.event.KeyEvent.VK_BACK_SPACE + s;
        log("bs = '" + bs + "'");
        return bs;
    }

    public boolean pasteMode() {
        return pasteMode;
    }

    public boolean pasteMode(boolean newMode) {
        pasteMode = newMode;
        return pasteMode;
    }

    public boolean SendTimerStart() {
        startTime = System.currentTimeMillis();
        SendLock();
        rcvBuf = "";
        try {
            serialPort.removeEventListener();
        } catch (Exception e) {
        }
        try {
            if (DumbMode.isSelected()) {
                serialPort.addEventListener(new PortReader(), portMask);
            } else {
                serialPort.addEventListener(new PortExtraReader(), portMask);
            }
        } catch (SerialPortException e) {
            log("数据发送器: 添加EventListener错误。取消了。");
            return false;
        }
        int delay = 0;
        j0();
        if (DumbMode.isSelected()) { // DumbMode
            delay = LineDelay.getValue();
            if (OptionNodeMCU.isSelected()) {
                taskPerformer = new ActionListener() {
                    public void actionPerformed(ActionEvent evt) {
                        if (j < sendBuf.size()) {
                            send(addCRLF(sendBuf.get(j).trim()), false);
                            inc_j();
                            int div = sendBuf.size() - 1;
                            if (div == 0) {
                                div = 1; // for non-zero divide
                            }
                            ProgressBar.setValue((j * 100) / div);
                            if (j > sendBuf.size() - 1) {
                                timer.stop();
                                StopSend();
                            }
                        }
                    }
                };
            } else { // MicroPython
                taskPerformer = new ActionListener() {
                    public void actionPerformed(ActionEvent evt) {
                        if (j < sendBuf.size()) {
                            if ((j == 0) && pasteMode()) {
                                sendStart();
                            }
                            send(addCRLF(sendBuf.get(j)), false);
                            inc_j();
                            if ((j == sendBuf.size()) && pasteMode()) {
                                sendEnd();
                            }
                            int div = sendBuf.size() - 1;
                            if (div == 0) {
                                div = 1; // for non-zero divide
                            }
                            ProgressBar.setValue((j * 100) / div);
                            if (j > sendBuf.size() - 1) {
                                timer.stop();
                                pasteMode(true);
                                StopSend();
                            }
                        }
                    }
                };
            }
            timer = new Timer(delay, taskPerformer);
            timer.setRepeats(true);
            timer.setInitialDelay(delay);
            timer.start();
            log("数据发送器: 开始 \"静音模式\"");
        } else { // SmartMode
            delay = Delay.getValue();
            if (delay == 0) {
                delay = 10;
            }
            taskPerformer = new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    if (j < sendBuf.size()) {
                        log(Integer.toString(j));
                        send(addCRLF(sendBuf.get(j).trim()), false);
                        sendPending = false;
                    }
                }
            };
            timer = new Timer(delay, taskPerformer);
            timer.setRepeats(false);
            timer.setInitialDelay(delay);
            timer.start();
            log("数据发送器: 开始 \"智能模式\"");
            WatchDog();
        }
        return true;
    }

    public void send(String s, boolean simple) {
        if (!pOpen) {
            log("数据发送器: 串口未打开，操作失败。");
            return;
        }
        if (busyIcon) {
            Busy.setIcon(LED_BLUE);
            SnippetsBusy.setIcon(LED_BLUE);
        } else {
            Busy.setIcon(LED_RED);
            SnippetsBusy.setIcon(LED_RED);
        }
        busyIcon = !busyIcon;
        try {
            log("发送:" + s.replace("\r\n", "<CR><LF>"));
            serialPort.writeString(s);
        } catch (SerialPortException ex) {
            log("发送失败:" + s.replace("\r\n", "<CR><LF>"));
        }
        if (!DumbMode.isSelected() && !simple) {
            try {
                timeout.restart();
            } catch (Exception e) {
            }
        }
        if (simple) {
            Busy.setIcon(LED_GREY);
            SnippetsBusy.setIcon(LED_GREY);
        }
    }

    public void sendBin(byte data) {
        if (!pOpen) {
            log("数据发送器: 串口未打开，操作失败。");
            return;
        }
        try {
            serialPort.writeByte(data);
        } catch (SerialPortException ex) {
            log("发送失败:" + (char) data);
        }
    }

    public void sendStart() {
        byte data = 0x05;
        sendBin(data);
    }

    public void sendEnd() {
        byte data = 0x04;
        sendBin(data);
    }

    public void Busy() {
        Busy.setText("繁忙");
        Busy.setBackground(new java.awt.Color(153, 0, 0)); // RED
        SnippetsBusy.setText("繁忙");
        SnippetsBusy.setBackground(new java.awt.Color(153, 0, 0)); // RED
        ProgressBar.setValue(0);
        ProgressBar.setVisible(true);
        FileSendESP.setEnabled(false);
        MenuItemFileSendESP.setEnabled(false);
        MenuItemFileRemoveESP.setEnabled(false);
        NodeReset.setEnabled(false);
        FileDo.setEnabled(false);
        MenuItemFileDo.setEnabled(false);
        MenuItemEditSendSelected.setEnabled(false);
        MenuItemEditorSendSelected.setEnabled(false);
        ButtonSendSelected.setEnabled(false);
        MenuItemEditSendLine.setEnabled(false);
        MenuItemEditorSendLine.setEnabled(false);
        ButtonSendLine.setEnabled(false);
        SnippetRun.setEnabled(false);
        ButtonSnippet0.setEnabled(false);
        ButtonSnippet1.setEnabled(false);
        ButtonSnippet2.setEnabled(false);
        ButtonSnippet3.setEnabled(false);
        ButtonSnippet4.setEnabled(false);
        ButtonSnippet5.setEnabled(false);
        ButtonSnippet6.setEnabled(false);
        ButtonSnippet7.setEnabled(false);
        ButtonSnippet8.setEnabled(false);
        ButtonSnippet9.setEnabled(false);
        ButtonSnippet10.setEnabled(false);
        ButtonSnippet11.setEnabled(false);
        ButtonSnippet12.setEnabled(false);
        ButtonSnippet13.setEnabled(false);
        ButtonSnippet14.setEnabled(false);
        ButtonSnippet15.setEnabled(false);
    }

    public void SendLock() {
        Busy();
        FileSaveESP.setText("取消");
        FileSaveESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/abort.png")));
        FileSaveESP.setSelected(true);
    }

    public void Idle() {
        Busy.setText("空闲");
        Busy.setBackground(new java.awt.Color(0, 153, 0)); // GREEN
        Busy.setIcon(LED_GREY);
        SnippetsBusy.setText("空闲");
        SnippetsBusy.setBackground(new java.awt.Color(0, 153, 0)); // GREEN
        SnippetsBusy.setIcon(LED_GREY);
        ProgressBar.setVisible(false);
        FileSendESP.setSelected(true);
        UpdateButtons();
        UpdateEditorButtons();
    }

    public void UpdateLED() {
        pOpen = Open.isSelected();
        if (!pOpen) {
            PortDTR.setIcon(LED_GREY);
            PortRTS.setIcon(LED_GREY);
            PortCTS.setIcon(LED_GREY);
            Open.setText("打开");
            Open.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/connect1.png")));
            PortOpenLabel.setIcon(LED_GREY);
            return;
        }
        Open.setText("关闭");
        Open.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/disconnect1.png")));
        PortOpenLabel.setIcon(LED_GREEN);
        UpdateLedCTS();
        if (PortDTR.isSelected()) {
            PortDTR.setIcon(LED_GREEN);
        } else {
            PortDTR.setIcon(LED_GREY);
        }
        if (PortRTS.isSelected()) {
            PortRTS.setIcon(LED_GREEN);
        } else {
            PortRTS.setIcon(LED_GREY);
        }
        if (portJustOpen) {
            PortOpenLabel.setIcon(LED_RED);
        }
    }

    public void SendUnLock() {
        Idle();
        FileSaveESP.setText("保存到ESP");
        FileSaveESP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/move.png")));
        FileSaveESP.setSelected(false);
        FileSendESP.setSelected(false);

        DisablingNotImplemented();

    }

    public void SetSnippetEditButtonsTooltip() {
        // should be called after loading, setting or editing any of the Snippet-Names
        // eg after SnippetSaveActionPerformed() and LoadSnippets ()
        // Mike, DL2ZAP 2015-01-04
        SnippetEdit0.setToolTipText(ButtonSnippet0.getText());
        SnippetEdit1.setToolTipText(ButtonSnippet1.getText());
        SnippetEdit2.setToolTipText(ButtonSnippet2.getText());
        SnippetEdit3.setToolTipText(ButtonSnippet3.getText());
        SnippetEdit4.setToolTipText(ButtonSnippet4.getText());
        SnippetEdit5.setToolTipText(ButtonSnippet5.getText());
        SnippetEdit6.setToolTipText(ButtonSnippet6.getText());
        SnippetEdit7.setToolTipText(ButtonSnippet7.getText());
        SnippetEdit8.setToolTipText(ButtonSnippet8.getText());
        SnippetEdit9.setToolTipText(ButtonSnippet9.getText());
        SnippetEdit10.setToolTipText(ButtonSnippet10.getText());
        SnippetEdit11.setToolTipText(ButtonSnippet11.getText());
        SnippetEdit13.setToolTipText(ButtonSnippet13.getText());
        SnippetEdit13.setToolTipText(ButtonSnippet13.getText());
        SnippetEdit14.setToolTipText(ButtonSnippet14.getText());
        SnippetEdit15.setToolTipText(ButtonSnippet15.getText());
    }

    boolean SaveDownloadedFile() {
        boolean success = false;
        log("保存下载的文件...");
        chooser.rescanCurrentDirectory();
        File f = new File(DownloadedFileName);
        javax.swing.filechooser.FileFilter flt = chooser.getFileFilter();
        chooser.resetChoosableFileFilters();
        chooser.setSelectedFile(f);
        chooser.setDialogTitle("保存从ESP文件下载 \"" + DownloadedFileName + "\" 为...");
        int returnVal = chooser.showSaveDialog(null);
        if (returnVal != JFileChooser.APPROVE_OPTION) {
            log("保存中止由用户。");
            return success;
        }
        f = chooser.getSelectedFile();
        chooser.setFileFilter(flt);
        DownloadedFileName = f.getName();
        SavePath();
        if (f.exists()) {
            log("文件 " + DownloadedFileName + " 已经存在，等待用户选择");
            int shouldWrite = Dialog("文件" + DownloadedFileName + "已存在，覆盖？", JOptionPane.YES_NO_OPTION);
            if (shouldWrite != JOptionPane.YES_OPTION) {
                log("保存已取消的用户，因为文件" + DownloadedFileName + "已经存在");
                return success;
            } else {
                log("文件" + DownloadedFileName + "将被用户选择覆盖");
            }
        } else { // we saving file, when open
            log("我们保存新文件" + DownloadedFileName);
        }
        try {
            log("尝试保存文件" + DownloadedFileName + " ...");
            fos = new FileOutputStream(f);
            fos.write(PacketsByte);
            fos.flush();
            log("保存文件" + DownloadedFileName + ": 成功, 大小:" + Long.toString(f.length()));
            success = true;
        } catch (Exception e) {
            log("保存文件" + DownloadedFileName + ": 失败.");
            log(e.toString());
            JOptionPane.showMessageDialog(null, "错误, 文件 " + DownloadedFileName + "没有被保存！");
        }
        try {
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            log(e.toString());
        }
        return success;
    }

    private void UploadFiles() {
        if (!pOpen) {
            log("上传器: 串口未打开，操作失败。");
            return;
        }
        if (portJustOpen) {
            log("上传器: 与MCU沟通尚未建立。");
            return;
        }
        chooser.rescanCurrentDirectory();
        javax.swing.filechooser.FileFilter flt = chooser.getFileFilter();
        chooser.resetChoosableFileFilters();
        chooser.setDialogTitle("选择文件上传到ESP");
        chooser.setMultiSelectionEnabled(true);
        int returnVal = chooser.showOpenDialog(LeftBasePane);
        mFile = new ArrayList<File>();
        log("上传器: 选择器选择文件:" + chooser.getSelectedFiles().length);
        if (mFile.addAll(Arrays.asList(chooser.getSelectedFiles()))) {
//        if ( mFile.add(chooser.getSelectedFile()) ) {
            mFileIndex = 0;
        } else {
            mFileIndex = -1;
            log("上传器:没有选择文件");
            return;
        }
        chooser.setFileFilter(flt);
//        chooser.setMultiSelectionEnabled(false);
        if (!(returnVal == JFileChooser.APPROVE_OPTION)) {
            log("上传器: 用户取消");
            return;
        }
        SavePath();
        UploadFilesStart();
    }

    private void UploadFilesStart() {
        UploadFileName = mFile.get(mFileIndex).getName();
        sendBuf = new ArrayList<String>();
        PacketsData = new ArrayList<String>();
        PacketsCRC = new ArrayList<Integer>();
        PacketsSize = new ArrayList<Integer>();
        PacketsNum = new ArrayList<Integer>();
        sendPacketsCRC = new ArrayList<Boolean>();
        rcvBuf = "";
        PacketsByte = new byte[0];
        rx_byte = new byte[0];
        tx_byte = new byte[0];

        if (!LoadBinaryFile(mFile.get(mFileIndex))) {
            log("上传器: 加载失败");
            return;
        }
        int lastPacketSize = SplitDataToPackets();
        if (lastPacketSize < 0) {
            log("上传器: 将数据分割成数据包失败!");
            return;
        }
        log("发送包=" + Integer.toString(sendPackets.size()));
        String cmd = "_up=function(n,l,ll)\n"
                + "     local cs = 0\n"
                + "     local i = 0\n"
                + "     print(\">\"..\" \")\n"
                + "     uart.on(\"data\", l, function(b) \n"
                + "          i = i + 1\n"
                + "          file.open(\"" + UploadFileName + "\",'a+')\n"
                + "          file.write(b)\n"
                + "          file.close()\n"
                + "          cs=0\n"
                + "          for j=1, l do\n"
                + "               cs = cs + (b:byte(j)*20)%19\n"
                + "          end\n"
                + "          uart.write(0,\"~~~CRC-\"..\"START~~~\"..cs..\"~~~CRC-\"..\"END~~~\")\n"
                + "          if i == n then\n"
                + "               uart.on(\"data\")\n"
                + "          end\n"
                + "          if i == n-1 and ll>0 then\n"
                + "               _up(1,ll,ll)\n"
                + "          end\n"
                + "          end,0)\n"
                + "end\n"
                + "file.remove(\"" + UploadFileName + "\")\n";
        sendBuf = cmdPrep(cmd);
        int startPackets;
        if (packets == 1) { // small file
            startPackets = lastPacketSize;
        } else {
            startPackets = SendPacketSize;
        }
        sendBuf.add("_up(" + Integer.toString(packets) + "," + Integer.toString(startPackets) + "," + Integer.toString(lastPacketSize) + ")");
        log("上传器: 开始...");
        startTime = System.currentTimeMillis();
        SendLock();
        rx_data = "";
        rcvBuf = "";
        try {
            serialPort.removeEventListener();
        } catch (Exception e) {
            log(e.toString());
        }
        try {
            serialPort.addEventListener(new PortFilesUploader(), portMask);
            log("上传器:添加EventListener:成功。");
        } catch (SerialPortException e) {
            log("上传器:添加EventListener错误。取消了。");
            SendUnLock();
            return;
        }
        int delay = 10;
        j0();
        taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                //log("send j="+Integer.toString(j));
                if (j < sendBuf.size()) {
                    send(addCR(sendBuf.get(j)), false);
                    sendPending = false;
                } else if ((j - sendBuf.size()) < sendPackets.size()) {
                    sendBytes(sendPackets.get(j - sendBuf.size()));
                    sendPending = false;
                } else {
                    log("抱歉，发现错误:j溢出");
                }
            }
        };
        timer = new Timer(delay, taskPerformer);
        timer.setRepeats(false);
        log("上传器: 开始");
        TerminalAdd("上传文件" + UploadFileName + "到ESP中...");
        timer.setInitialDelay(delay);
        WatchDog();
        timer.start();
    }

    private boolean LoadBinaryFile(File f) {
        boolean success = false;
        try {
            log("二进制文件加载器: 尝试加载文件 " + f.getName() + " ...");
            fis = new FileInputStream(f);
            DataInputStream dis = new DataInputStream(fis);
            tx_byte = new byte[dis.available()];
            int size = dis.read(tx_byte);
            dis.close();
            fis.close();
            if (size == f.length()) {
                log("二进制文件加载器: 加载文件" + f.getName() + ": 成功, 大小:" + Long.toString(f.length()));
                success = true;
            } else {
                log("二进制文件加载器: 加载文件" + f.getName() + ": 失败, 大小:" + Long.toString(f.length()) + ", 读:" + Integer.toString(size));
            }
        } catch (IOException e) {
            log("二进制文件加载器: 加载文件 " + f.getName() + ": 失败.");
            log(e.toString());
            JOptionPane.showMessageDialog(null, "二进制文件加载器: 错误, 文件 " + f.getName() + " 不能读取!");
        }
        return success;
    }

    private int SplitDataToPackets() {
        sendPackets = new ArrayList<byte[]>();
        packets = tx_byte.length / SendPacketSize;
        log("1. 包 = " + Integer.toString(packets));
        if ((tx_byte.length % SendPacketSize) > 0) {
            packets++;
        }
        log("2. 包 = " + Integer.toString(packets));
        if (tx_byte.length < SendPacketSize) {
            packets = 1;
        }
        int remain = tx_byte.length;
        int lastPacketSize = -1;
        byte[] b;
        int pos = 0;
        for (int i = 0; i < packets; i++) {
            log("3. 包 = " + Integer.toString(i));
            if (remain > SendPacketSize) {
                b = new byte[SendPacketSize]; // default value is 200
            } else {
                b = new byte[remain];
                lastPacketSize = remain;
            }
            System.arraycopy(tx_byte, pos, b, 0, b.length);
            sendPackets.add(b);
            log("二进制文件加载器: 准备下一个要发送的数据包, 长度=" + Integer.toString(b.length));
            remain -= b.length;
            pos += b.length;
        }
        log("二进制文件加载器: 总包的准备=" + Integer.toString(sendPackets.size()));
        return lastPacketSize;
    }

    public void sendBytes(byte[] b) {
        if (!pOpen) {
            log("二进制发送者: 串口未打开，操作失败。");
            return;
        }
        if (busyIcon) {
            Busy.setIcon(LED_BLUE);
            SnippetsBusy.setIcon(LED_BLUE);
        } else {
            Busy.setIcon(LED_RED);
            SnippetsBusy.setIcon(LED_RED);
        }
        busyIcon = !busyIcon;
        try {
            //log("二进制发送者 sending:" + b.toString().replace("\r\n", "<CR><LF>"));
            serialPort.writeBytes(b);
        } catch (SerialPortException ex) {
            log("二进制发送者 发送失败:" + b.toString().replace("\r\n", "<CR><LF>"));

        }
    }

    private class PortFilesUploader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            String data, crc_parsed;
            boolean gotProperAnswer = false;
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                try {
                    data = serialPort.readString(event.getEventValue());
                    rcvBuf = rcvBuf + data;
                    rx_data = rx_data + data;
                    //log("rcv:"+data);
                } catch (Exception e) {
                    data = "";
                    log(e.toString());
                }
                if (rcvBuf.contains("> ") && j < sendBuf.size()) {
                    //log("got intepreter answer, j="+Integer.toString(j));
                    rcvBuf = "";
                    gotProperAnswer = true;
                }
                if (rx_data.contains("~~~CRC-END~~~")) {
                    gotProperAnswer = true;
                    //log("上传器: receiving packet checksum " + Integer.toString( j-sendBuf.size()  +1) + "/"
                    //                                           + Integer.toString( sendPackets.size() ) );
                    // parsing answer
                    int start = rx_data.indexOf("~~~CRC-START~~~");
                    //log("Before CRC parsing:"+rx_data);
                    crc_parsed = rx_data.substring(start + 15, rx_data.indexOf("~~~CRC-END~~~"));
                    rx_data = rx_data.substring(rx_data.indexOf("~~~CRC-END~~~") + 13);
                    //log("After  CRC parsing:"+crc_parsed);
                    int crc_received = Integer.parseInt(crc_parsed);
                    int crc_expected = CRC(sendPackets.get(j - sendBuf.size()));
                    if (crc_expected == crc_received) {
                        log("上传器: 接收校验 " + Integer.toString(j - sendBuf.size() + 1) + "/"
                                + Integer.toString(sendPackets.size())
                                + " 校验: 成功");
                        sendPacketsCRC.add(true);
                    } else {
                        log("上传器: 接收校验" + Integer.toString(j - sendBuf.size() + 1) + "/"
                                + Integer.toString(sendPackets.size())
                                + " 校验: 失败. 预期的: " + Integer.toString(crc_expected)
                                + ", 但是接收了: " + Integer.toString(crc_received));
                        sendPacketsCRC.add(false);
                    }
                }
                if (gotProperAnswer) {
                    try {
                        timeout.restart();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    ProgressBar.setValue(j * 100 / (sendBuf.size() + sendPackets.size() - 1));
                    if (j < (sendBuf.size() + sendPackets.size())) {
                        if (timer.isRunning() || sendPending) {
                            //
                        } else {
                            inc_j();
                            sendPending = true;
                            timer.start();
                        }
                    } else {
                        try {
                            timer.stop();
                        } catch (Exception e) {
                        }
                    }
                }
                if (j >= (sendBuf.size() + sendPackets.size())) {
                    LocalEcho = false;
                    send(addCR("_up=nil"), false);
                    try {
                        timer.stop();
                    } catch (Exception e) {
                    }
                    try {
                        timeout.stop();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    //log("上传器: send all data, finishing...");
                    boolean success = true;
                    for (int i = 0; i < sendPacketsCRC.size(); i++) {
                        if (!sendPacketsCRC.get(i)) {
                            success = false;
                        }
                    }
                    if (success && (sendPacketsCRC.size() == sendPackets.size())) {
                        TerminalAdd("成功\r\n");
                        log("上传器: 成功");
                    } else {
                        TerminalAdd("失败\r\n");
                        log("上传器: 失败");
                    }
                    try {
                        serialPort.removeEventListener();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    try {
                        serialPort.addEventListener(new PortReader(), portMask);
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    StopSend();
                    if (mFileIndex != -1 && mFileIndex++ < mFile.size()) {
                        UploadFilesStart();
                    }
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("文件管理器：接收到未知的串口错误。");
            }
        }
    }

    private void ViewFile(String fn) {
        String cmd = "_view=function()\n"
                + "local _line\n"
                + "if file.open(\"" + fn + "\",\"r\") then \n"
                + "    print(\"--FileView start\")\n"
                + "    repeat _line = file.readline() \n"
                + "        if (_line~=nil) then \n"
                + "            print(string.sub(_line,1,-2)) \n"
                + "        end \n"
                + "    until _line==nil\n"
                + "    file.close() \n"
                + "    print(\"--FileView done.\") \n"
                + "else\n"
                + "  print(\"\\r--FileView error: can't open file\")\n"
                + "end\n"
                + "end\n"
                + "_view()\n"
                + "_view=nil\n";
        LocalEcho = false;
        SendToESP(cmdPrep(cmd));
    }

    private void SetFirmwareType(int ftype) {
        FirmwareType = ftype;
        switch (ftype) {
            case FIRMWARE_MPYTHON:
                prefs.put(FIRMWARE, "MicroPython");
                PrefsFlush();
                chooser.setFileFilter(FILTER_PYTHON);
                CommandsSetMicroPython();
                OptionMicroPython.setSelected(true);
                CommandsMicroPython.setVisible(true);
                CommandsNodeMCU.setVisible(false);
                NodeFileManagerPane.setVisible(false);
                PyFileManagerPane.setVisible(true);
                DisablingNotImplemented();
                break;
            case FIRMWARE_NODEMCU:
                prefs.put(FIRMWARE, "NodeMCU");
                PrefsFlush();
                chooser.setFileFilter(FILTER_LUA);
                CommandsSetNodeMCU();
                OptionNodeMCU.setSelected(true);
                CommandsMicroPython.setVisible(false);
                CommandsNodeMCU.setVisible(true);
                NodeFileManagerPane.setVisible(true);
                PyFileManagerPane.setVisible(false);
                break;
            default:
                // AT-based
                prefs.put(FIRMWARE, "AT");
                PrefsFlush();
                chooser.setFileFilter(FILTER_ALL);
                CommandsSetAT();
                break;
        }
        LoadSnippets(); // reloading needed
    }

    private void DisablingNotImplemented() {
        if (OptionMicroPython.isSelected()) {
            /* temporay disabling not emplemented functions */
            LineDelay.setValue(0); // micro python very fast :)
            DumbMode.setSelected(true);

            MenuItemViewLeftExtra.setSelected(false);
            //MenuItemViewFileManager.setSelected(false);
            MenuItemViewRightExtra.setSelected(false);
            MenuItemViewDonate.setSelected(false);
            MenuItemFileDo.setEnabled(false);
            FileDo.setEnabled(false);
            MenuItemFileRemoveESP.setEnabled(false);
            MenuESP.setEnabled(false);
            FilesUpload.setEnabled(false);
            //MenuItemFileSaveESP.setEnabled(false);
            //FileSaveESP.setEnabled(false);

            FileAutoSaveESP.setSelected(false);
            Condensed.setSelected(false);
            Condensed.setEnabled(false);

            /* enabled items */
            MenuItemViewSnippets.setEnabled(true);

        }
    } // DisablingNotImplemented

    private void cmdButtonGPIO(int gpio, int value) {
        if (!OptionMicroPython.isSelected()) {
            return;
        }
        if (!pOpen) {
            log("端口未打开，操作失败。");
            return;
        }
        if (portJustOpen) {
            log("错误:与MCU未建立通信。");
            return;
        }
        log("发送GPIO命令 " + Integer.toString(gpio) + " : " + Integer.toString(value));
        String cmd = "from machine import Pin; p = Pin(" + Integer.toString(gpio) + ", Pin.OUT, value=" + Integer.toString(value) + ")";
        btnSend(cmd);
    } // cmdButtonGPIO

    private void cmdButtonGetGPIO(int gpio) {
        if (!OptionMicroPython.isSelected()) {
            return;
        }
        if (!pOpen) {
            log("端口未打开，操作失败。");
            return;
        }
        if (portJustOpen) {
            log("错误:与MCU未建立通信。");
            return;
        }
        log("发送命令获取GPIO" + Integer.toString(gpio));
        String cmd = "from machine import Pin; p = Pin(" + Integer.toString(gpio) + ", Pin.IN); p.value()";
        btnSend(cmd);
    }

    private boolean pySaveFileESP(String ft) {
        boolean success = false;
        log("py文件保存到ESP: 开始...");
        String[] content = TextEditor1.get(iTab).getText().split("\r?\n");
        if (PYFILER.Put(ft, content)) {
            pasteMode(false);
            success = SendTimerStart();
        }
        return success;
    } // pySaveFileESP

    private void AddPyFileButton(String FileName) {
        PyFileAsButton.add(new javax.swing.JButton());
        int i = PyFileAsButton.size() - 1;
        PyFileAsButton.get(i).setText(FileName);
        PyFileAsButton.get(i).setAlignmentX(0.5F);
        PyFileAsButton.get(i).setMargin(new java.awt.Insets(2, 2, 2, 2));
        PyFileAsButton.get(i).setMaximumSize(new java.awt.Dimension(130, 25));
        PyFileAsButton.get(i).setPreferredSize(new java.awt.Dimension(130, 25));
        PyFileAsButton.get(i).setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        PyFileAsButton.get(i).addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PyFileAsButton1ActionPerformed(evt);
            }
        });
        // PopUp menu
        FilePopupMenu.add(new javax.swing.JPopupMenu());
        int x = FilePopupMenu.size() - 1;
        int y;
        // PopUp menu items
        /*
        if (FileName.endsWith(".py")) {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/lua.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", LeftClick - Run, RightClick - Other actions");
            AddMenuItemRun(x, FileName);
            AddMenuItemCompile(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemView(x, FileName);
            AddMenuItemDump(x, FileName);
            AddMenuItemEdit(x, FileName, size);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        } else if (FileName.endsWith(".lc")) {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/lc.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", LeftClick - Run, RightClick - Other actions");
            AddMenuItemRun(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemDump(x, FileName);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        } else {
            FileAsButton.get(i).setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/file.png")));
            FileAsButton.get(i).setToolTipText(FileAsButton.get(i).getActionCommand() + ", LeftClick - View, RightClick - Other actions");
            AddMenuItemView(x, FileName);
            AddMenuItemDump(x, FileName);
            AddMenuItemEdit(x, FileName, size);
            AddMenuItemDownload(x, FileName, size);
            AddMenuItemRename(x, FileName);
            AddMenuItemSeparator(x);
            AddMenuItemRemove(x, FileName);
        }

        FileAsButton.get(i).setComponentPopupMenu(FilePopupMenu.get(x));
         */
        PyFileManagerPane.add(PyFileAsButton.get(i));

    } // AddPyFileButton

    private void ClearPyFileManager() {
        if (!MenuItemViewFileManager.isSelected()) {
            return;
        }
        PyFileManagerPane.removeAll();
        PyFileManagerPane.add(PyListDir);
        PyFileManagerPane.repaint();
        PyFileAsButton = new ArrayList<javax.swing.JButton>();
    } // ClearPyFileManager

    private void PyListFiles() {
        if (portJustOpen) {
            log("错误:未与MCU建立通信。");
            return;
        }
        try {
            serialPort.removeEventListener();
        } catch (Exception e) {
            log(e.toString());
            return;
        }
        try {
            serialPort.addEventListener(new PortPyFilesReader(), portMask);
            log("py文件管理器： 添加EventListener:成功。");
        } catch (SerialPortException e) {
            log("py文件管理器： 添加EventListener错误。取消了。");
            return;
        }
        ClearPyFileManager();
        rx_data = "";
        rcvBuf = "";
        log("py文件管理器： 开始...");
        String cmd = "import os;os.listdir('" + PYFILER.pwd() + "')";
        btnSend(cmd);
        WatchDogPyListDir();
    } // PyListFiles

    private void WatchDogPyListDir() {
        watchDog = (ActionEvent evt) -> {
            //StopSend();
            Toolkit.getDefaultToolkit().beep();
            TerminalAdd("等待ESP的答复-超时到了。命令中止。");
            log("ESP应答超时。命令中止。");
            try {
                serialPort.removeEventListener();
                serialPort.addEventListener(new PortReader(), portMask);
            } catch (SerialPortException e) {
                log(e.toString());
            }
            SendUnLock();
        };
        int delay = AnswerDelay.getValue() * 1000;
        if (delay == 0) {
            delay = 300;
        }

        timeout = new Timer(delay, watchDog);
        timeout.setRepeats(false);
        timeout.setInitialDelay(delay);
        timeout.start();
    } // WatchDogPyListDir

    private class PortPyFilesReader implements SerialPortEventListener {

        @Override
        public void serialEvent(SerialPortEvent event) {
            String data;
            if (event.isRXCHAR() && event.getEventValue() > 0) {
                try {
                    data = serialPort.readString(event.getEventValue());
                    rcvBuf = rcvBuf + data;
                    rx_data = rx_data + data;
                    TerminalAdd(data);
                } catch (SerialPortException e) {
                    log(e.toString());
                }
                if (rx_data.contains("']\r\n>>>")) {
                    try {
                        timeout.stop();
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    log("文件管理器: 文件列表找到!做解析……");
                    try {
                        int start = rx_data.indexOf("[");
                        rx_data = rx_data.substring(start + 1, rx_data.indexOf("]"));
                        rx_data = rx_data.replace("'", "");
                        s = rx_data.split(", ");
                        Arrays.sort(s);
                        TerminalAdd("\r\n----------------------------");
                        for (String subs : s) {
                            TerminalAdd("\r\n" + subs);
                            if (subs.trim().length() > 0) {
                                AddPyFileButton(subs);
                                log("文件管理器发现文件" + subs);
                            }
                        }
                        if (PyFileAsButton.isEmpty()) {
                            TerminalAdd("没有找到文件");
                        }
                        TerminalAdd("\r\n----------------------------\r\n> ");
                        PyFileManagerPane.invalidate();
                        PyFileManagerPane.doLayout();
                        PyFileManagerPane.repaint();
                        PyFileManagerPane.requestFocusInWindow();
                        log("py文件管理器： 文件列表解析完成，找到 " + PyFileAsButton.size() + " 文件");
                    } catch (Exception e) {
                        log(e.toString());
                    }
                    try {
                        serialPort.removeEventListener();
                        serialPort.addEventListener(new ESPlorer.PortReader(), portMask);
                    } catch (SerialPortException e) {
                        log(e.toString());
                    }
    //                    SendUnLock();
                }
            } else if (event.isCTS()) {
                UpdateLedCTS();
            } else if (event.isERR()) {
                log("文件管理器: 接收到未知的串行端口错误。");
            }
        } // serialEvent
    } // PortPyFilesReader

} // ESPlorer
